From 400d11ea4fe580e21f59838d14d8b8dcd8970fbc Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Tue, 13 Oct 2026 06:57:07 +0100 Subject: [PATCH] ci: least-privilege release publishing, no persisted tokens, pinned audit, checksums - Release Builds: the build/test matrix ran ~1,400 third-party build scripts and tests with a contents:write token persisted in .git/config. It now runs with contents:read and persist-credentials: false; a separate publish job (no project or dependency code) downloads the artefacts, writes SHA256SUMS and attaches both to the release. The release now waits for every platform instead of publishing partially. - CI/Fuzz checkouts don't persist credentials; cargo-audit is pinned (0.22.2), fails on yanked crates, and also audits fuzz/Cargo.lock; fuzz runs set -timeout=10 so slow-input bugs (like the IRC OSC one) are reported instead of hiding under libFuzzer's 20-minute default. - updates/index.php: array-valued query parameters no longer raise TypeErrors/warnings; nosniff header. --- .github/workflows/ci.yml | 12 ++++++++--- .github/workflows/fuzz.yml | 4 +++- .github/workflows/release-builds.yml | 31 +++++++++++++++++++++++----- updates/index.php | 9 +++++--- 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b41c9e..f57c86f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,6 +22,8 @@ jobs: working-directory: rust steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - name: Linux dependencies (GUI libs, and sshd for the SSH integration tests) if: runner.os == 'Linux' run: | @@ -39,6 +41,10 @@ jobs: working-directory: rust steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 - - run: cargo install cargo-audit --locked - # Ignored advisories and their reasons live in rust/.cargo/audit.toml. - - run: cargo audit + with: + persist-credentials: false + - run: cargo install cargo-audit --version 0.22.2 --locked + # Ignored advisories and their reasons live in rust/.cargo/audit.toml. Yanked crates + # fail the build; the fuzz workspace has its own lockfile, so it's audited too. + - run: cargo audit --deny yanked + - run: cargo audit --deny yanked --file fuzz/Cargo.lock diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 678f4e6..a8d6b0f 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -21,10 +21,12 @@ jobs: working-directory: rust/fuzz steps: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false - run: sudo apt-get update && sudo apt-get install -y libasound2-dev - run: rustup toolchain install nightly --profile minimal - run: cargo +nightly install cargo-fuzz --locked - - run: cargo +nightly fuzz run ${{ matrix.target }} -- -max_total_time=120 -rss_limit_mb=2048 + - run: cargo +nightly fuzz run ${{ matrix.target }} -- -max_total_time=120 -rss_limit_mb=2048 -timeout=10 - name: Upload crashing inputs if: failure() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 diff --git a/.github/workflows/release-builds.yml b/.github/workflows/release-builds.yml index 89a8a72..5fd29a2 100644 --- a/.github/workflows/release-builds.yml +++ b/.github/workflows/release-builds.yml @@ -6,8 +6,10 @@ on: - "v*" workflow_dispatch: +# Building and testing runs every dependency's build scripts and tests, so those jobs only get a +# read token. Publishing is a separate job that never runs project or dependency code. permissions: - contents: write + contents: read jobs: build: @@ -31,6 +33,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: fetch-depth: 0 + persist-credentials: false - name: Rust toolchain (pinned by rust-toolchain.toml) run: rustup show active-toolchain || rustup toolchain install @@ -59,8 +62,26 @@ jobs: build/releases/manifest-*.json build/releases/version-*.txt - - name: Attach to GitHub Release - if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2 + publish: + name: Attach to GitHub Release + needs: build + if: startsWith(github.ref, 'refs/tags/') + runs-on: ubuntu-22.04 + permissions: + contents: write + steps: + - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: - files: build/releases/*/NexusTerminal-*.zip + path: artefacts + - name: Checksums + run: | + find artefacts -name 'NexusTerminal-*.zip' | while read -r f; do + (cd "$(dirname "$f")" && sha256sum "$(basename "$f")") + done > SHA256SUMS + cat SHA256SUMS + - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2.6.2 + with: + files: | + artefacts/*/*/NexusTerminal-*.zip + artefacts/*/NexusTerminal-*.zip + SHA256SUMS diff --git a/updates/index.php b/updates/index.php index 87f337d..33f7cb5 100644 --- a/updates/index.php +++ b/updates/index.php @@ -1,6 +1,8 @@