Skip to content

[actions] Alternate actions/checkout paths suppress untrusted-checkout alerts #22213

Description

@1sgtpepper

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions