From 5fde1edb696a71d2547eaeef91668c57597517d4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 20 Jun 2026 13:55:41 +0000 Subject: [PATCH] fix(security): resolve three deferred Hypatia findings (CodeQL/scorecard/setup) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - codeql.yml: add `language: rust` to the CodeQL matrix so the Rust source (the primary implementation) gets real SAST, not just the GitHub Actions workflows. The `actions` entry already satisfied the stale "lacks actions" finding; this makes SAST non-nominal. - scorecard-enforcer.yml: de-publish the enforcer. scorecard.yml (the reusable workflow) already publishes results, so the enforcer's publish was redundant and placed a privileged publish step (id-token / security-events) next to a custom run: score-gate. Set publish_results: false, drop the upload-sarif step, and reduce the job to contents: read. The score gate still runs on the locally generated results.sarif. Resolves scorecard_publish_with_run_step. - setup.sh: replace the two `curl … | bash` just installers (CWE-494) with install_just_pinned(): pin just 1.53.0, map platform/arch to the release target, download the tarball over HTTPS, verify SHA256, then extract+install — failing closed on mismatch. Usage comment now documents download-review-run instead of pipe-to-shell. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Y2MWTAqX2x7goVJzjFB4j5 --- .github/workflows/codeql.yml | 2 + .github/workflows/scorecard-enforcer.yml | 10 +-- setup.sh | 100 ++++++++++++++++++++--- 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index ba87ffe..5de8946 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -33,6 +33,8 @@ jobs: include: - language: actions build-mode: none + - language: rust + build-mode: none steps: - name: Checkout diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 57535d0..6163099 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -25,8 +25,7 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 permissions: - security-events: write - id-token: write # For OIDC + contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -37,12 +36,7 @@ jobs: with: results_file: results.sarif results_format: sarif - publish_results: true - - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v4 - with: - sarif_file: results.sarif + publish_results: false - name: Check minimum score run: | diff --git a/setup.sh b/setup.sh index 4be2b1c..ad6a8bc 100755 --- a/setup.sh +++ b/setup.sh @@ -5,10 +5,14 @@ # Detects your shell, platform, and installs prerequisites. # Then hands off to `just setup` for project-specific configuration. # -# Usage: -# curl -fsSL https://raw.githubusercontent.com/hyperpolymath/wokelangiser/main/setup.sh | sh -# # or after cloning: +# Usage (recommended — download, review, then run; don't pipe straight to a shell): +# curl -fsSL https://raw.githubusercontent.com/hyperpolymath/wokelangiser/main/setup.sh -o setup.sh +# less setup.sh # review before running +# sh setup.sh +# # …or after cloning: # ./setup.sh +# # Convenience one-liner (review the script first — you are trusting the network): +# curl -fsSL https://raw.githubusercontent.com/hyperpolymath/wokelangiser/main/setup.sh | sh # # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) @@ -128,6 +132,86 @@ detect_platform() { esac } +# ── Verified install of just (pinned version + SHA256; avoids curl|sh, CWE-494) ── +# Bump JUST_VERSION and the four SHA256 values together from: +# https://github.com/casey/just/releases (each release publishes SHA256SUMS) +install_just_pinned() { + JUST_VERSION="1.53.0" + + # Map platform/arch -> just release target triple + that tarball's SHA256. + just_target="" + just_sha256="" + case "$OS:$ARCH" in + linux:x86_64|linux:amd64) + just_target="x86_64-unknown-linux-musl" + just_sha256="7fedeb22c7e14d9ef1551e8b793700866d80f409f9884b0e80ebb65c11d4874d" ;; + linux:aarch64|linux:arm64) + just_target="aarch64-unknown-linux-musl" + just_sha256="f29d8e72380bc144465f632c7d59da311205eef2923d57511708b05b82f2e64f" ;; + macos:x86_64|macos:amd64) + just_target="x86_64-apple-darwin" + just_sha256="bc345a26d40ae4697cb6b2f2ca04cdf1fbdc8c50eba1b40684c8bf3f98555d72" ;; + macos:arm64|macos:aarch64) + just_target="aarch64-apple-darwin" + just_sha256="27f1361f2e4fb5d733837f1a9f80f85c237e5a36c75ee14961e59141713aa4ed" ;; + *) + fail "No pinned 'just' build for $OS/$ARCH — install manually: https://just.systems/" + return 1 ;; + esac + + # Need a checksum tool (Linux: sha256sum, macOS: shasum -a 256). + if ! command -v sha256sum >/dev/null 2>&1 && ! command -v shasum >/dev/null 2>&1; then + fail "Need sha256sum or shasum to verify the download — install one, or get just manually: https://just.systems/" + return 1 + fi + + just_tarball="just-${JUST_VERSION}-${just_target}.tar.gz" + just_url="https://github.com/casey/just/releases/download/${JUST_VERSION}/${just_tarball}" + + info "Installing just ${JUST_VERSION} (${just_target}): download, verify SHA256, then install" + + tmpdir=$(mktemp -d 2>/dev/null) || { fail "Could not create temp dir"; return 1; } + + # 1) Download over HTTPS to a file (no pipe-to-shell). + if ! curl -fsSL "$just_url" -o "${tmpdir}/${just_tarball}"; then + fail "Download failed: $just_url" + rm -rf "$tmpdir"; return 1 + fi + + # 2) Verify integrity BEFORE touching the contents (this is the CWE-494 fix). + if command -v sha256sum >/dev/null 2>&1; then + actual_sha=$(sha256sum "${tmpdir}/${just_tarball}" | awk '{print $1}') + else + actual_sha=$(shasum -a 256 "${tmpdir}/${just_tarball}" | awk '{print $1}') + fi + if [ "$actual_sha" != "$just_sha256" ]; then + fail "Checksum mismatch for ${just_tarball} — refusing to install" + fail " expected: $just_sha256" + fail " actual: $actual_sha" + rm -rf "$tmpdir"; return 1 + fi + ok "Checksum verified (SHA256)" + + # 3) Extract only the verified binary and install it. + if ! tar -xzf "${tmpdir}/${just_tarball}" -C "$tmpdir" just; then + fail "Could not extract just from ${just_tarball}" + rm -rf "$tmpdir"; return 1 + fi + + if [ -w /usr/local/bin ]; then + cp "${tmpdir}/just" /usr/local/bin/just && chmod 0755 /usr/local/bin/just + else + sudo cp "${tmpdir}/just" /usr/local/bin/just && sudo chmod 0755 /usr/local/bin/just + fi + rc=$? + + rm -rf "$tmpdir" + if [ "$rc" -ne 0 ]; then + fail "Could not install just to /usr/local/bin" + return 1 + fi +} + # ── Install just ── install_just() { if command -v just >/dev/null 2>&1; then @@ -139,10 +223,7 @@ install_just() { case "$PKG_MGR" in dnf) sudo dnf install -y just ;; - apt) sudo apt-get install -y just 2>/dev/null || { - # just not in older apt repos — use installer - curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin - } ;; + apt) sudo apt-get install -y just 2>/dev/null || install_just_pinned ;; pacman) sudo pacman -S --noconfirm just ;; apk) sudo apk add just ;; brew) brew install just ;; @@ -151,10 +232,7 @@ install_just() { rpm-ostree) sudo rpm-ostree install just ;; guix) guix install just ;; nix) nix-env -iA nixpkgs.just ;; - *) - info "Using just installer script..." - curl -fsSL https://just.systems/install.sh | bash -s -- --to /usr/local/bin - ;; + *) install_just_pinned ;; esac if command -v just >/dev/null 2>&1; then