りゅーそうブログ

「Postmortem: TanStack npm supply-chain compromise」をみた

開発

2026/05/12 22:56

tanstackのサプライチェーン侵害の感想を書いてみる。

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

ここではこのサプライチェーン攻撃の要因について考えてみたい。

pull_request_targetの利用

tanstackのリポジトリに対する悪意あるForkに対し、base repository 権限で実行される pull_request_target でのworkflow実行環境を与えてしまっていたというのが根本原因である。

その上で、 ref: refs/pull/${{ github.event.pull_request.number }}/mergeでチェックアウトからの pnpm nx run @benchmarks/bundle-size:build でのビルドを実行してしまっていた。

つまり高権限内での外部PRコード実行をおこなってしまっていたことが大きな問題だったと言える。ちなみにこの pull_request_target の利用については、

GitHubの公式のセキュリティガイドに

必要がない場合は、pull_request_target ワークフロー トリガーを使わないでください。 ワークフロー間の特権の分離には、workflow_run の方が適切なトリガーです。 ワークフローで実際に特権コンテキストが必要な場合にのみ、これらのワークフロー トリガーを使ってください。

信頼されていない pull request またはコード コンテンツで pull_request_target および workflow_run ワークフロー トリガーを使うことは避けてください。 これらのトリガーを使うワークフローでは、(pull request のフォークや自分の管理下にないリポジトリなどの) 信頼されていないコードを明示的にチェックアウトしてはなりません。 workflow_run 上でトリガーされるワークフローでは、他のワークフローからアップロードされた成果物を慎重に扱う必要があります。

引用:https://docs.github.com/ja/enterprise-server@3.18/actions/reference/security/secure-use#mitigating-the-risks-of-untrusted-code-checkout

とある。このようなセキュリティのベストプラクティスを遵守すること、何よりGiuHub Actionsの権限の分離が重要であるという教訓を改めて感じた。最近のサプライチェーンはこのようなCI/CDの信頼境界を狙った攻撃が増えている。

攻撃の流れ

その後の攻撃の流れとしては、攻撃者は悪意のあるコードをGitHub Actions の actions/cache(pnpm-cache)にパッケージを混入→actions/cacheは同じキーであればworkflow間で共有されるため、本番のrelease workflowで悪意あるコードが含まれたcacheがrestore→release workflowでpublishされたOIDC Tokenを搾取というのが大まかな流れである。

この流れのどれが欠けていても攻撃は成立しなかったので、流れとしては複雑に思える。

そもそもpublishでcacheを利用することへの是非、cache keyの分離などの対策が考えられるだろう。tanstackのポストモーテムにもこのcache poisoningに対して

This is the class of attack documented by Adnan Khan in 2024. It's not a TanStack-specific bug; it's a known GitHub Actions design issue that requires conscious mitigation.

引用:https://tanstack.com/blog/npm-supply-chain-compromise-postmortem#2-github-actions-cache-poisoning-across-trust-boundaries

と言っているようにAIで新規に編み出された攻撃手法ではなく既存の攻撃を学習して、巧妙に穴をついた攻撃であったことを示唆している。またOIDCの搾取の手法についても

This is the same memory-extraction technique (and verbatim Python script, with attribution comment) used in the tj-actions/changed-files compromise of March 2025. The attacker did not invent novel tradecraft; they recombined published research.

引用:https://tanstack.com/blog/npm-supply-chain-compromise-postmortem#3-oidc-token-extraction-from-runner-memory

と既知の手法の組み合わせによっての攻撃であったと述べている。

まとめ

今回のtanstackのサプライチェーンのpostmortemの詳細なレポートにまずは感謝したい。個人的にはどのリポジトリも完全な防御は困難とされている中で、数十分でのパッケージ公開の被害に抑えたというのは被害の中では最小だと思われるので、外部の協力者からの発見とあったが不幸中の幸いだったように思える。

攻撃手法のスムーズさを考えると複雑なものに見えるし、AI時代の高度なものに見えるが一つ一つを見ると、セキュリティのプラクティスに沿っていれば防げるようなものであった(まあそれが難しいのではあるが....)。

既知の攻撃手法なので防げる攻撃でもあるように思う。

今回の件は、CI/CDを単なるビルド基盤ではなく「本番権限を持つ実行環境」として扱う必要があることを改めて示したように思う。