|
55 | 55 | ) |
56 | 56 |
|
57 | 57 | steps: |
| 58 | + # ───────────────────────────────────────────────────────────────── |
| 59 | + # CodeQL alert #14 (untrusted-checkout-toctou/critical) was |
| 60 | + # dismissed on 2026-05-14 as "won't fix" with the rationale |
| 61 | + # documented below. The dismissal is valid ONLY while ALL of |
| 62 | + # the following hold: |
| 63 | + # 1. The Codex action runs with sandbox: read-only (see the |
| 64 | + # Run Codex step below). No step EXECUTES PR-head FILE |
| 65 | + # BYTES — no `pip install -e .`, `pytest`, `npm install`, |
| 66 | + # `cargo run`, `make`, `./configure`, `maturin develop`, |
| 67 | + # or `python3 <pr-file>.py` against checked-out PR-head |
| 68 | + # files. Inline `python3 -c '...'` invocations operating |
| 69 | + # on sanitized environment variables (PR_TITLE, PR_BODY, |
| 70 | + # PREV_REVIEW) are SAFE — the script body comes from base, |
| 71 | + # not from PR head. |
| 72 | + # 2. The fork-skip gate (`is_fork == 'false'`) gates every |
| 73 | + # post-resolve step, including both actions/checkout |
| 74 | + # invocations. |
| 75 | + # 3. The author_association check on issue_comment / |
| 76 | + # review-comment events restricts triggers to |
| 77 | + # OWNER/MEMBER/COLLABORATOR. |
| 78 | + # 4. head_sha is API-pinned in this resolve-pr step before |
| 79 | + # checkout. |
| 80 | + # |
| 81 | + # If you are adding a step that VIOLATES any of these |
| 82 | + # invariants, this dismissal is invalid. Either remove the |
| 83 | + # offending step OR restructure the workflow to checkout |
| 84 | + # BASE_SHA only and use `git show` for PR-head reads (degrades |
| 85 | + # reviewer quality — see plan archive). |
| 86 | + # |
| 87 | + # Guard test: tests/test_openai_review.py |
| 88 | + # ::TestWorkflowDoesNotExecutePRHeadCode |
| 89 | + # Catches the common ACCIDENTAL-regression forms: pip / npm / |
| 90 | + # yarn / cargo / make / maturin / poetry / pdm / uv / tox / |
| 91 | + # setup.py install/run, python file execution against PR-head |
| 92 | + # paths, bash -c / sh -c (including compound flags -lc/-ec/-exc) |
| 93 | + # with python/cp inside, env-var prefixes (`VAR=1 python3 ...`), |
| 94 | + # wrapper commands (`env`, `nohup`, `exec`, `time`, `command`), |
| 95 | + # shell negation (`!`), backslash line continuations, single-line |
| 96 | + # `python3 -c` payloads (literal-allowlisted, currently empty), |
| 97 | + # subshell `(...)`, brace group `{ ...; }`, and write-overwrites |
| 98 | + # of allowlisted /tmp paths between staging and execution |
| 99 | + # (`>`, `>>`, `cp`, `mv`, `tee`, `ln`). |
| 100 | + # |
| 101 | + # NOT exhaustive against an adversarial maintainer. Known |
| 102 | + # unmodeled paths (any of these CAN execute PR-head bytes |
| 103 | + # without tripping CI; a maintainer reviewing this workflow |
| 104 | + # MUST refuse changes that introduce them): |
| 105 | + # - bash <script> / sh <script> / ./<script> / source <script> |
| 106 | + # / . <script> — direct shell-script execution |
| 107 | + # - multi-line `python3 -c` bodies (line-by-line shlex can't |
| 108 | + # reassemble across newlines; the workflow's existing 5 |
| 109 | + # sanitizer bodies are therefore exempt by invisibility) |
| 110 | + # - variable expansion: `SCRIPT="$X"; python3 "$SCRIPT"` |
| 111 | + # - `eval`, `find -exec`, `xargs -I {}` |
| 112 | + # The dismissal's primary defense is THIS comment block plus |
| 113 | + # the `dismissed_comment` field on alert #14. The guard test |
| 114 | + # is belt-and-suspenders for accidental regressions, not a |
| 115 | + # complete adversarial parser. |
| 116 | + # See TODO.md for the long-term tracking of this gap. |
| 117 | + # ───────────────────────────────────────────────────────────────── |
58 | 118 | - name: Resolve PR number + metadata |
59 | 119 | id: pr |
60 | 120 | uses: actions/github-script@v9 |
|
0 commit comments