Description of the issue
actions/untrusted-checkout/critical does not report a privileged workflow that checks out an untrusted PR into a non-default path: and then executes a script or local action from that checkout. The actions/untrusted-checkout/high fallback is also suppressed, so neither query reports the workflow.
Minimal reproducer
on: pull_request_target
permissions:
contents: write
jobs:
execute:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.sha }}
path: candidate
- run: bash candidate/proof.sh
actions/checkout places path: candidate under $GITHUB_WORKSPACE, so this executes the same checked-out script relationship as a default checkout followed by bash proof.sh.
Reproduction
The complete reproducer is in public fork PR #1.
- Latest-release fork CI: CodeQL Action 4.37.1, CLI 2.26.1,
codeql/actions-queries 0.6.31
- Current-main CI: queries compiled directly from
github/codeql@14450f5bf38ea9a3ce2e0e45dcf51c0bbdd01af5
Both successful runs scanned all 11 workflow files and produced the same result matrix:
| Case |
Result |
Default checkout followed by bash proof.sh |
actions/untrusted-checkout/critical |
Default checkout followed by uses: ./.github/actions/proof |
actions/untrusted-checkout/critical |
Default checkout with quoted or $GITHUB_WORKSPACE script paths |
actions/untrusted-checkout/critical |
path: candidate, ./candidate, or candidate/ followed by the corresponding script |
no critical or high alert |
path: candidate followed by uses: ./candidate/.github/actions/proof |
no critical or high alert |
| Immutable checkout control |
no critical or high alert |
The CI also executed harmless script and composite-action canaries through the tested paths before analysis.
Expected result
The alternate-path cases should be reported by actions/untrusted-checkout/critical, like their default-path controls. A path-representation mismatch should not suppress both the critical query and its high fallback.
Source-level cause
At current main:
Normalizing explicit actions/checkout paths at the checkout model, with regression tests for bare, dot-relative, trailing-slash, and local-action forms, appears to be the smallest fix.
Description of the issue
actions/untrusted-checkout/criticaldoes not report a privileged workflow that checks out an untrusted PR into a non-defaultpath:and then executes a script or local action from that checkout. Theactions/untrusted-checkout/highfallback is also suppressed, so neither query reports the workflow.Minimal reproducer
actions/checkoutplacespath: candidateunder$GITHUB_WORKSPACE, so this executes the same checked-out script relationship as a default checkout followed bybash proof.sh.Reproduction
The complete reproducer is in public fork PR #1.
codeql/actions-queries0.6.31github/codeql@14450f5bf38ea9a3ce2e0e45dcf51c0bbdd01af5Both successful runs scanned all 11 workflow files and produced the same result matrix:
bash proof.shactions/untrusted-checkout/criticaluses: ./.github/actions/proofactions/untrusted-checkout/critical$GITHUB_WORKSPACEscript pathsactions/untrusted-checkout/criticalpath: candidate,./candidate, orcandidate/followed by the corresponding scriptpath: candidatefollowed byuses: ./candidate/.github/actions/proofThe CI also executed harmless script and composite-action canaries through the tested paths before analysis.
Expected result
The alternate-path cases should be reported by
actions/untrusted-checkout/critical, like their default-path controls. A path-representation mismatch should not suppress both the critical query and its high fallback.Source-level cause
At current
main:ActionsMutableRefCheckout.getPath()andActionsSHACheckout.getPath()return explicit checkout paths verbatim.LocalScriptExecutionRunStep.getPath()and local-action paths are normalized intoGITHUB_WORKSPACE/...form.isSubpath, while the high query suppresses its fallback because the following step is still aPoisonableStep.Normalizing explicit
actions/checkoutpaths at the checkout model, with regression tests for bare, dot-relative, trailing-slash, and local-action forms, appears to be the smallest fix.