GitHub Actions is a trap

Tyler Cipriani

GitHub Actionsは罠だ

原文は Tyler Cipriani により に公開されました。 このブログを購読する

ハッカーがパッケージを次々と乗っ取るペースはうんざりするほど速く、どの事後検証レポートにもGitHub Actionsの名前が出てくる。

2月下旬、自称hackerbot AI1と名乗る何者かが、ある一つのプロジェクトのリリースキーをかすめ取った。1か月も経たないうちに、50ほどのプロジェクトに認証情報を盗むコードが仕込まれた。感染したリポジトリが、次々と次の認証情報を奪っていったのだ。

この一連のサプライチェーン攻撃は、GitHub Actionsの罠から始まった。単純で質の悪いデフォルト設定と、5年前から提案されたまま放置されている修正だ。

GitHub Actionsとその代償

GitHub Actionsの罠について警告するアドミラル・アクバー
GitHub Actionsの罠について警告するアドミラル・アクバー

Trivyはオープンソースのセキュリティスキャナーだ。だが3月下旬にTrivyを使っていたなら、ひどい目に遭ったはずだ。

3月19日、ハッカーは実行された環境からシークレットを片っ端から外部に持ち出そうとするTrivyのバージョンをプッシュした。Trivy側は、継続的インテグレーション(CI)システムであるGitHub Actionsの「設定ミス」が原因だと説明した。

しかしこれは設定ミスというより、GitHub Actionsに仕掛けられた罠だった。

Trivyがどのようにハックされたのか、簡略化した例がこちらだ2

# INSECURE. DO NOT USE.
on:
  pull_request_target

jobs:
  check:
    steps:
      - uses: action/checkout@deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
        with:
          ref: refs/pull/${{ github.event.pull_request.number }}/merge
      - uses: ./.github/actions/setup-go
      - uses: some/go-static-analysis@c0ffeec0ffeec0ffeec0ffeec0ffeec0ffeec0ff

一見すると、このコードは問題なく見える:

  • シークレットを参照していない。
  • サードパーティのActionは不変のハッシュでピン留めされている。
  • プルリクエストをチェックアウトして静的解析を行うだけだ。

だがこのコードは、2021年のGitHubブログ記事「preventing pwn requests」で文字通りそのままアンチパターンとして紹介されていたものだ:

もしpull_request_targetワークフローが […] 信頼できないコードを実行するだけで、シークレットを参照していなかったとしても、脆弱なのだろうか?

答えはイエスだ

GitHub Security Lab

問題はpull_request_targetにある:

  • pull_request_target — 環境に美味しそうなGITHUB_TOKENをポンと置いてくれる。
  • actions/checkoutpersist-credentialsという任意のパラメータがあり、falseに設定すればシークレットを削除してくれる。だがこのパラメータのデフォルトはtrueだ。

persist-credentialsパラメータをfalseにすべきだという指摘は、2021年からGitHub Actionsの未解決のissueとして残されたままだ2021年から

君の$HOMEは犯罪現場だ

ハッカーはTrivyのキーを手に入れると、さらに多くのキーを盗むためにTrivyの新しいバージョンを公開した。

LiteLLMはCIでTrivyを使っていた。しかもそれは、PythonのソフトウェアレジストリであるPyPIへコードを公開するのと同じCIだ。LiteLLMのCIが汚染されたTrivyを実行したとき、ハッカーはその公開キーを奪い取った。

そして3月24日、Callum McMahonがIDEを立ち上げると、MacBookがフリーズした。それがLiteLLMハイジャック発覚のきっかけだった。

McMahonのMacBookは、ハッカーがLiteLLMに忍び込ませた不正なコードに振り回されていた。そのコードが盗もうとしていた認証情報は次のとおりだ:

  • ~/.netrc
  • ~/.aws/credentials
  • ~/.config/gcloud
  • ~/.config/gh
  • ~/.azure
  • ~/.docker/config.json
  • ~/.npmrc
  • ~/.git-credentials
  • ~/.kube/

いずれも$HOMEディレクトリに無造作に置かれていることが多く、トークンやキーが詰まっているのに、しばしば暗号化すらされていないファイルだ。

AIとサプライチェーン破滅のスパイラル

暗号化されていない認証情報、ピン留めされていない依存関係、CIの自爆スイッチといった問題には、ずっと前から悩まされてきた。

だがAIはすべてを加速させた。セキュリティ上の過ちの繰り返しまでもだ。

Trivyが侵害された当日、私はClaudeにこう尋ねた。「Dockerレジストリのイメージを脆弱性スキャンするにはどうすればいい?」

その回答の一部がこちらだ:

CI/CD Integration Example (GitHub Actions with Trivy)

    - name: Scan image for vulnerabilities
      uses: aquasecurity/trivy-action@master

2つの点で間違っている:

  1. ピン留めされていない参照 — masterは常に変わりうる参照だ。もしハッカーがリポジトリをゾンビ化すれば、私が最初の被害者になる。
  2. 既知の脆弱性 — その日に公開されたCVEについて一切触れていない。私が尋ねなかったから、Claudeも確認しなかったのだ。

一方、VercelのCEOは最近のデータ侵害について、犯人は「AIによって加速された」ハッカーだったと説明している。そしてAnthropicは最新の誇大宣伝ツアーの中で、自社のフロンティアモデルが発見した脆弱性について米連邦準備制度理事会議長に説明まで行っている。

LLMを手にした悪者は超能力を得る。LLMを手にした善人は2010年代半ばのCIの問題に足をすくわれる。

そして、OpenBSDに27年間潜んでいたセキュリティ問題を掘り起こせる同じツールが、GitHub Actionsは@masterでピン留めしろと平然と教えてくるのだ。


  1. もっとも、自称hackerbot-clawと名乗る何者か、ではあるが。↩︎

  2. 私が挙げたGitHub Actionsの例は、aquasecurity/trivy #10259で削除されたActionを簡略化したものだ。↩︎

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント