fix(security): resolve the CodeQL backlog, three fixes and three documented false positives (#1225)
Triage of all 9 CodeQL alerts surfaced on main by #1223. None were introduced by that PR. Fixed: the compliance-review artifact now unpacks to runner.temp instead of over the trusted checkout (actions/artifact-poisoning, critical); MCP LIKE patterns escape backslash first, which was a real correctness bug returning wrong rows for any search containing a backslash (js/incomplete-sanitization, 2 sites); and the mcp-oauth consent form action is HTML-escaped (js/reflected-xss, not exploitable because WHATWG URL already percent-encodes " < >, but & is not in that encode set). Dismissed as false positives with reasoning recorded at each site and in DECISIONS.md: sie-export escapeQuotes, where doubling backslashes would violate SIE 4B, corrupt files in conformant readers and skew #KSUMMA under BFL 7-year retention; hashApiKey, where SHA-256 is correct for a 256-bit CSPRNG token and changing it would invalidate every live gnubok_sk_ key; and the DuplicateBookingDialog href, which is a DB UUID behind a literal path prefix. Regression tests cover both behavioural fixes, including the escape ordering.
This commit is contained in:
@@ -43,13 +43,25 @@ jobs:
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
|
||||
with:
|
||||
name: compliance-input
|
||||
# Unpacked OUTSIDE the checkout, not into the workspace root.
|
||||
#
|
||||
# This artifact is built from a fork's PR head, so its contents are
|
||||
# attacker-influenced. Extracted over the workspace, an entry named
|
||||
# `scripts/swedish-compliance-review.mjs` would overwrite the trusted
|
||||
# script this job is about to run, with the AWS secrets and a write
|
||||
# token already in scope. Stage 1 only ever writes three fixed
|
||||
# filenames, and its workflow definition comes from the base repo even
|
||||
# for fork PRs, so that is not reachable today: this keeps it
|
||||
# unreachable if stage 1 ever grows a filename derived from PR
|
||||
# content. Flagged by CodeQL as actions/artifact-poisoning.
|
||||
path: ${{ runner.temp }}/compliance-input
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Resolve PR number
|
||||
id: pr
|
||||
run: |
|
||||
set -euo pipefail
|
||||
NUM=$(cat pr-number.txt)
|
||||
NUM=$(cat "$RUNNER_TEMP/compliance-input/pr-number.txt")
|
||||
# Guard: pr-number.txt must be a plain integer (artifact is untrusted input).
|
||||
if ! [[ "$NUM" =~ ^[0-9]+$ ]]; then
|
||||
echo "Refusing to continue: pr-number.txt is not a number" >&2
|
||||
@@ -81,8 +93,8 @@ jobs:
|
||||
AWS_REGION: ${{ secrets.AWS_REGION || 'eu-north-1' }}
|
||||
REVIEW_MODEL: eu.anthropic.claude-sonnet-5
|
||||
# Two-stage mode: read the diff from the artifact instead of git-diffing.
|
||||
DIFF_FILE: diff.patch
|
||||
FILES_FILE: files.txt
|
||||
DIFF_FILE: ${{ runner.temp }}/compliance-input/diff.patch
|
||||
FILES_FILE: ${{ runner.temp }}/compliance-input/files.txt
|
||||
run: node scripts/swedish-compliance-review.mjs
|
||||
- name: Assert review produced output
|
||||
# This job once produced no compliance signal for 10 consecutive PR
|
||||
|
||||
Reference in New Issue
Block a user