github / github/codeql

Actions: Extractor for external actions and workflows does not take into account the ref

Offen
#21,834 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
question
Vorherrschende Sprache
CodeQL
Sterne
10.1k
Forks
2.1k
Ø Merge
2 T. 15 Std.
Gemergte PRs (30 T.)
141

Beschreibung

I'm trying to add external workflows to the repo before calling CodeQL. This would allow me to recurse into composite actions and callable workflows not defined in the same repo.

This would help detect cache poisoning attacks and unsafe checkouts from composite actions and callable workflows defined in different repos that the one being scanned. As well as other unsafe constructs inside these workflows and actions our organization might rely on.

The attack on tanstack, is an example of how the actual actions/cache call was "hidden" in a composite action:

https://tanstack.com/blog/npm-supply-chain-compromise-postmortem

```yaml
on:
pull_request_target:
paths: ['packages/**', 'benchmarks/**']

jobs:
benchmark-pr:
steps:
- uses: actions/checkout@v6.0.2
with:
ref: refs/pull/${{ github.event.pull_request.number }}/merge # fork's merged code

- uses: TanStack/config/.github/setup@main # transitively calls actions/cache@v5
```

Currently, when storing external composite actions and callable workflows in `.github/actions/external/` the actions are ingested and scanned along with the repos own workflows and thus more issues can be detected.

**But** the folder structure doesn't take into account the ref of the action, so I can only put a single implementation in, before scanning.

# Why this is inherent to the CodeQL extractor's design
Looking at the CodeQL QL library conventions:

`CompositeActionImpl.getResolvedPath()` strips `.github/actions/external/` → result is `actions/checkout`

The uses: string is `actions/checkout@v5` — the QL library matches by path prefix, not by exact `uses:` string

So the CodeQL extractor itself doesn't support multiple versions of the same action at different refs. The directory convention has no slot for the version/ref.

# Impact
When multiple workflows in the same repo use different versions of the same action, such as: `actions/checkout@v5` and `actions/checkout@v6`, it's only possible to place one of these versions in the expected `external` folder.

This results in:
* Incorrect analysis results: CodeQL may analyze v6's `action.yml` when the workflow actually uses v5, or vice versa. If the actions differ in their internal `uses:` or `run:` steps between versions, this could produce false positives or false negatives.
* Non-deterministic: The result depends on the order dependencies are processed.
Possible mitigations

# Proposed solution:

Ensure the `ref` is somehow part of (or supported in) the directory structure:

```
.github/actions/external/actions/checkout/{ref}/path/action.yaml
```

Given that refs themselves can contain `/` and other unsupported characters, and that they may actually point to a different sha between runs, it might be even better to resolve the ref to a sha and when stored under that path:

```
.github/actions/external/actions/checkout/{sha}/path/action.yaml
```

That would result in the most predictable scans.

This may require a sha->ref lookup in order to resolve to the right composite action.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne mit der Konvention `.github/actions/external/` und dem für `CompositeActionImpl.getResolvedPath()` beschriebenen Verhalten der CodeQL-QL-Bibliothek. Verfolge, wie `uses:`-Werte wie `actions/checkout@v5` und `@v6` abgeglichen werden, und lege anschließend fest, wie Refs oder aufgelöste SHAs dargestellt werden sollen. Als erledigt gilt die Aufgabe, wenn unterschiedliche Refs derselben externen Action oder desselben Workflows deterministisch eingelesen und analysiert werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
github-actions
Bereich
devtools, security
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.