From c71f2cd667016a7681beadb7fe5d174e28ecc817 Mon Sep 17 00:00:00 2001 From: ozymandiashh <234437643+ozymandiashh@users.noreply.github.com> Date: Wed, 5 Aug 2026 03:21:29 +0300 Subject: [PATCH] ci: make the bracket-assign guard actually match its targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prototype-pollution rule has never fired. Its `paths.include` named the pre-workspace layout (`/src/providers/*.ts`, `/src/parser.ts`) while the job scans `packages/cli/src/...`, so the rule selected no files and the step was green unconditionally. Verified before and after: with the old rule and the old scan targets a planted bracket-assign under packages/cli/src/providers/ reports 0 findings; with this change the same violation is reported at the right file and line, and the real tree scans 184 files clean. Also brings packages/core/src/providers/** into scope. Provider decoding moved there in the extraction, so that is where records from untrusted session logs are now turned into maps — precisely what the rule exists to guard. Two guard-rails so the step cannot silently go vacuous again: - The step now fails when the scan selected no files. semgrep's --json `paths.scanned` reflects what the rule actually selected, not the raw scan targets (verified: with the include paths broken but the targets intact, scanned drops to 0 while the step still exits 0). A low-water mark was considered and rejected as brittle: the provider count is a moving target by design and CI installs semgrep unpinned, so a magic number would need constant bumping and would decay back into vacuity. - The CLI providers glob is now recursive (`**/*.ts`) like core's. The directory is flat today, but a future nested provider directory would be scanned by CI and then silently excluded by the rule; a planted violation under providers/nested/ is now reported. The narrow whitelist is deliberate and unchanged in spirit: unrelated maps elsewhere in the tree stay out of scope. --- .github/workflows/ci.yml | 7 ++++++- .semgrep/rules/no-bracket-assign-hot-paths.yml | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab7616c5..42a8887f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,12 @@ jobs: set -e semgrep --config .semgrep/rules/no-bracket-assign-hot-paths.yml \ --strict --json \ - packages/cli/src/providers/ packages/cli/src/parser.ts > semgrep-out.json + packages/cli/src/providers/ packages/cli/src/parser.ts packages/core/src/providers/ > semgrep-out.json + SCANNED=$(jq '.paths.scanned | length' semgrep-out.json) + if [ "$SCANNED" -eq 0 ]; then + echo "::error::semgrep scanned no files — the rule's paths.include no longer matches any scan target; check .semgrep/rules/no-bracket-assign-hot-paths.yml" + exit 1 + fi FINDINGS=$(jq '.results | length' semgrep-out.json) if [ "$FINDINGS" -gt 0 ]; then jq -r '.results[] | "::error file=\(.path),line=\(.start.line)::\(.extra.message)"' semgrep-out.json diff --git a/.semgrep/rules/no-bracket-assign-hot-paths.yml b/.semgrep/rules/no-bracket-assign-hot-paths.yml index e2e633da..fe12ffb5 100644 --- a/.semgrep/rules/no-bracket-assign-hot-paths.yml +++ b/.semgrep/rules/no-bracket-assign-hot-paths.yml @@ -18,5 +18,6 @@ rules: ... paths: include: - - '/src/providers/*.ts' - - '/src/parser.ts' + - '/packages/cli/src/providers/**/*.ts' + - '/packages/cli/src/parser.ts' + - '/packages/core/src/providers/**/*.ts'