Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions .github/workflows/build-platform-tfms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ name: Build platform-specific TFMs
on:
workflow_dispatch:

permissions:
contents: read

jobs:
ios:
name: Build net10.0-ios
Expand All @@ -29,10 +32,10 @@ jobs:
runs-on: macos-14
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

- name: Install ios workload
run: dotnet workload install ios
Expand All @@ -47,10 +50,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

- name: Install android workload
run: dotnet workload install android
Expand All @@ -68,10 +71,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

- name: Install wasm-tools workload
run: dotnet workload install wasm-tools
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
push:
branches: [master]

permissions:
contents: read

# One CI run per ref at a time; a push flurry cancels superseded runs
# instead of stacking them. (Once, 18 concurrently-hung runs exhausted the
# account's ~20 concurrent-job quota and starved every other workflow.)
Expand Down Expand Up @@ -51,7 +54,7 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

# global.json pins the SDK floor at 10.0.300 (with
# `rollForward: latestFeature`, so any 10.0.3xx-or-newer SDK
Expand All @@ -63,7 +66,7 @@ jobs:
# global.json when no version is given, installing the requested
# floor on the runner if it isn't already present.
- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

# GitHub-hosted runners exist for Windows, Linux, and macOS but NOT
# for iOS, Android, or browser WebAssembly. Those TFMs are
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: CodeQL

# Static analysis for the C# surface of this repo — runs on every push/PR to
# master plus a weekly schedule, so newly-added CodeQL query patterns get a
# chance to flag existing code, not just new diffs.
#
# Scoped to net10.0 on ubuntu-latest via CI_TFMS (the same mechanism
# ci.yml's ubuntu leg uses): CodeQL needs one successful build to extract
# from, and the platform TFMs (ios/android/macos/browser) need workloads
# and runners this leg doesn't have — build-platform-tfms.yml and
# release.yml already compile-check those separately.

on:
push:
branches: [master]
pull_request:
branches: [master]
schedule:
- cron: '24 3 * * 1' # weekly, Monday 03:24 UTC

concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze (C#)
runs-on: ubuntu-latest
timeout-minutes: 20
# Job-level permissions replace (not merge with) any workflow-level
# block, so both grants live here even though only one job exists —
# scoping them to the job that actually needs them, not the workflow.
permissions:
contents: read
security-events: write
env:
CI_TFMS: net10.0
steps:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
Comment thread
coderabbitai[bot] marked this conversation as resolved.
with:
persist-credentials: false

- name: Setup .NET
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

- name: Initialize CodeQL
uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4
with:
languages: csharp

- name: Restore
run: dotnet restore

- name: Build
run: dotnet build TopSecret.ProtectedString.sln --configuration Release --no-restore

- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4
2 changes: 1 addition & 1 deletion .github/workflows/dependabot-auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
- name: Fetch Dependabot metadata
id: meta
uses: dependabot/fetch-metadata@v3
uses: dependabot/fetch-metadata@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7

# Honours global.json (SDK floor 10.0.300, rollForward latestFeature).
- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

- name: Install wasm-tools workload
run: dotnet workload install wasm-tools
Expand Down Expand Up @@ -78,10 +78,10 @@ jobs:
echo "bundle=$bundle" >> "$GITHUB_ENV"

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v5
uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5
with:
path: ${{ env.bundle }}

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
tag: ${{ steps.rp.outputs.tag_name }}
steps:
- id: rp
uses: googleapis/release-please-action@v5
uses: googleapis/release-please-action@45996ed1f6d02564a971a2fa1b5860e934307cf7 # v5
with:
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
Expand Down Expand Up @@ -81,12 +81,12 @@ jobs:
echo "version=${TAG#v}" >> "$GITHUB_OUTPUT"

- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
with:
ref: ${{ steps.tag.outputs.name }}

- name: Setup .NET
uses: actions/setup-dotnet@v5
uses: actions/setup-dotnet@26b0ec14cb23fa6904739307f278c14f94c95bf1 # v5

# macos-14 is the only hosted runner where all five installs succeed —
# required for the main library's six-TFM pack.
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ The fork's fix (v2.0.0) runs the first lane inline on the calling thread and dis

The 32-byte process master key plus its protector live once per process, regardless of how many `ProtectedString`s you allocate. Memory locking has a per-process budget on libc targets — see [Memory-locking policy](#memory-locking-policy) for the budget number and the failure-behaviour knob.

Content length is checked against 32-bit overflow before encryption: a plaintext at or beyond `int.MaxValue / 2` UTF-16 chars (~1.07 billion, since each char becomes 2 ciphertext bytes) throws `OverflowException` instead of silently under-allocating. In practice you'll hit `Array.MaxLength` or run out of process memory well before that threshold.

## Build & test

```
Expand Down
47 changes: 47 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Security Policy

## Supported versions

Only the latest published version of each package (currently `2.x`) receives
security fixes. There is no LTS branch — given the release cadence, upgrading
is expected to be the fix.

## Reporting a vulnerability

Please **do not open a public GitHub issue** for a suspected vulnerability —
in the memory-protection guarantees (secrets recoverable from a memory or
core dump, a key-wrapping tier not doing what it claims, a timing
side-channel in a comparison, a wipe that doesn't happen on some exit path)
or in the supply chain (a CI/release workflow that could be tricked into
running untrusted code or exfiltrating secrets).

Instead, use GitHub's private vulnerability reporting for this repository:
[Report a vulnerability](https://github.com/Alpaq92/TopSecret.ProtectedString/security/advisories/new).

Include, where you can:

- The affected package(s) and version.
- A description of the weakness and, if possible, a minimal repro.
- The platform/TFM it applies to, if platform-specific — this library's
security guarantees differ by key-at-rest tier; see the README's
[Security model](README.md#security-model) section.

## Response

This is a solo-maintained project with no formal SLA. Reports are triaged
and acknowledged as soon as reasonably possible, and a confirmed
vulnerability is prioritized over new feature work.

## Scope

**In scope:** the packages in this repository (`TopSecret.ProtectedString`,
`TopSecret.ProtectedBlob`, the TPM/Configuration satellites, and the Roslyn
analyzer) and the GitHub Actions workflows that build, test, and release
them.

**Out of scope:** the demo apps (`TopSecret.Demo`, `TopSecret.Demo.Wasm`)
except where a demo bug points at a real library issue, and anything already
documented as a known, deliberate limitation in the README's
["What this library does **not** do"](README.md#what-this-library-does-not-do-and-why)
section — those are accepted trade-offs, not vulnerabilities, unless you can
show the trade-off is worse in practice than documented.
7 changes: 6 additions & 1 deletion TopSecret.Demo.Wasm/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,14 @@
unthemed by default — the browser renders it (track, thumb, and
especially the corner where the vertical scrollbar meets the
bottom edge) in its native light colours regardless of page
theme, showing up as a stray white patch in dark mode. */
theme, showing up as a stray white patch in dark mode.
xterm.css also hardcodes background-color: #000 on the viewport
and (as of xterm 6) never re-syncs it to the theme, so the
leftover strip below the last full row of cells shows through
as a black bar in light mode. */
#terminal .xterm-viewport {
scrollbar-color: var(--border) var(--bg);
background-color: var(--bg);
}
#terminal .xterm-viewport::-webkit-scrollbar {
width: 10px;
Expand Down
2 changes: 1 addition & 1 deletion TopSecret.ProtectedString/ProtectedString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,7 @@ private void EncryptInternal(ReadOnlySpan<char> plain)
// change which key we encrypt under mid-operation.
Debug.Assert(_instanceProtector is not null, "InitInstance must run before EncryptInternal");

int byteLen = plain.Length * 2;
int byteLen = checked(plain.Length * 2);

// Allocate (and lock) the new state up front. If anything in here
// throws — e.g., the configured policy is Throw and a lock failed —
Expand Down
Loading