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

オープン
#21,834 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
45/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
静か
技術スタック
github-actions
領域
devtools, security

調査の方向性

.github/actions/external/ の規約と、CompositeActionImpl.getResolvedPath() について説明されている CodeQL QL ライブラリの動作から始めます。actions/checkout@v5@v6 のような uses: の値がどのように照合されるかを追跡し、その後、ref または解決済み SHA をどのように表現するかを定義します。同じ外部 action または workflow の異なる ref が決定論的に取り込まれ、分析されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

question

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

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.

主要言語
CodeQL
スター
10.1k
フォーク
2.1k
平均マージ
2日 11時間
マージ済み PR(30日)
129

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

github/codeql のほかの issue

github/codeql の issue をすべて見る

似ている issue

DevTools の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。