SecurityWeek の記事は、オープンソース界隈をまたぐかなり大きな supply chain attack を報じています。
名前は Mini Shai-Hulud。なんだかSFみたいな名前ですが、やっていることは地味に恐ろしいです。
ざっくり言うと、開発者や企業が普通に使っている NPM や PyPI のパッケージに悪意あるコードを混ぜ込み、利用者の環境で secrets を盗み出す攻撃です。
ここでいう secrets は、ログイン情報、API key、クラウドの認証情報、GitHub token みたいな「持っていると他人になりすませる情報」全般のこと。要するに、デジタル世界の鍵束ですね。
しかも今回の攻撃は、ただの雑な改ざんではなく、正規の配布経路そのものを悪用しているのがポイントです。
ここが本当にいやらしい。パッケージが「公式っぽく見える」どころか、仕組み上はちゃんと正規に見えてしまう。これでは検知が難しいのも納得です。
記事によると、影響を受けたのは次のような人気プロジェクトです。

特に TanStack は、React / Vue / Solid など複数のフロントエンド界隈で広く使われるので、weekly downloads が多いのも厄介です。
つまり、直接そのプロジェクトを知らなくても、どこかのアプリの中で“間接的に”踏んでしまう可能性があるわけです。サプライチェーン攻撃の怖さはまさにここにあります。
記事では、この攻撃は TeamPCP と呼ばれるグループの犯行だとされています。
このグループはここ数か月、複数のオープンソース・エコシステムで supply chain attack を繰り返してきたとのこと。
正直、こういう攻撃者は「一発当てて終わり」ではなく、仕組み化して何度もやるのが厄介です。
しかも今回は、Dune 由来の名前を使った branch や、"Shai-Hulud: Here We Go Again" という説明文まで出てきていて、かなり“シリーズもの”感があります。悪ふざけっぽく見えて、実際にはかなり計画的です。
Mini Shai-Hulud は、以下のような情報を狙っていました。
要するに、「あると困るもの」を片っ端から抜きに来ています。
しかもただ盗むだけでなく、感染を広げる機能まで持っているのが本当に悪質です。
感染した端末の GitHub / NPM 権限を使って、次の悪性版を公開していく。完全に“自己増殖型”の設計です。

今回とくに面白いのは、TanStack のケースです。
ここでは、攻撃者が 3つの既知の脆弱性・弱点をつなげて 攻撃を成立させています。
pull_request_target の悪用GitHub Actions の pull_request_target は、使い方を間違えると危険です。
簡単に言うと、外部から来た pull request に対して、本来は信用すべきでないコードを高い権限で実行してしまうことがある仕組みです。
これをセキュリティ界隈では “Pwn Request” と呼ぶことがあります。
GitHub Actions の cache は、ビルドを速くする便利機能です。
でも trust boundary(信用してよい範囲)をまたいで汚染されると、後から正規のビルドが毒入り cacheを拾ってしまうことがあります。
今回、攻撃者はこの cache を汚し、のちのリリース工程に悪性データを混ぜ込みました。
さらに攻撃者は、GitHub Actions runner の process memory から OIDC token を取り出しました。
OIDC token は、クラウドやNPMなどで「このビルドは本物です」と証明するために使われるものです。
これが盗まれると、攻撃者は正規のビルド担当者になりすましてしまえます。
個人的には、ここが今回いちばんゾッとするポイントです。
「証明書付きだから安心」と思っていたものが、正規のパイプライン自体を乗っ取られることで逆に危険になる。
セキュリティの“信頼の鎖”が、そのまま攻撃者に利用されるわけです。
記事によると、盗まれた GitHub OIDC token を使うことで、攻撃者は 署名証明書 を取得できました。
その結果、悪性パッケージなのに SLSA provenance が付いた、正当なビルドのような見た目にできたのです。

SLSA provenance は、簡単にいうと「このソフトは信頼できる手順で作られました」という証明書のようなもの。
普通なら改ざん検知に役立つのですが、今回はその証明書を“本物の工程”から盗み取ってしまった。
これはかなり高度で、しかも実用的な攻撃です。見た目だけ整えてもダメ、という典型例ですね。
TanStack の全体では、同じ 2.3MB の implant が各パッケージの tarball に直接埋め込まれていたそうです。
ファイル名は router_init.js。
このコードは単なる情報窃取だけではなく、
まで含む、多段階の悪性コードでした。
fingerprinting は「端末や環境の特徴を調べて、どこで動いているか見分けること」です。
exfiltration は「盗んだデータを外に持ち出すこと」。
こういう用語は難しく聞こえますが、やっていることはかなり単純で、要は“見て、抜いて、送る”です。

Socket の分析では、この implant は Linux と macOS で別の収集経路を使い、クラウドネイティブな CI 環境にある主要な secrets を片っ端から漁っていたとのこと。
ここまで来ると、もはや「マルウェア」というより「開発環境ハンター」です。
盗まれた credentials は、以下の3経路で送られていたとされています。
https://git-tanstack[.]comSession network(*.getsession.org を使った暗号化通信)とくに面白いのが Session network 経由の exfiltration です。
これは分散型で、止めにくい通信ネットワーク。
Wiz は、通常の専用ドメインや GitHub ベースの送信よりも、取り締まりやすさの点で厄介だと指摘しています。
なるほどな、と思いました。
攻撃者は単に“悪いコード”を書くのではなく、止められにくい運び方まで考える。ここまで含めて攻撃設計なんですよね。

Guardrails AI と Mistral AI の PyPI パッケージには、NPM 版とは異なる payload が入っていたそうです。
Guardrails AI には、わずか 13行 のコードが追加されていて、git-tanstack[.]com から別の payload を取ってきて実行するようになっていました。
しかもこれは Linux 専用。
このモジュラー型の credential stealer は、より本格的に secrets を集め、さらに初めて 1Password や Bitwarden のような password manager まで狙っていたとされています。
password manager が狙われるのはかなりイヤですね。そこが抜かれると、被害は雪だるま式に広がります。
さらに、Israel や Iran の locale では、MP3 を最大音量で再生し、システム上のファイルを削除しようとする挙動もあったとのこと。
このあたりは破壊工作的な要素が強く、単なる窃取以上の意図が見えます。
記事では、5時間の間に 401件以上の malicious package artifacts が公開されたとされています。
そして、5月11日のキャンペーン全体では 170以上のパッケージ が影響を受けました。
この数字、じわじわ怖いです。
1個2個の“事故”ではなく、かなり短時間に広範囲へばら撒かれています。
しかも、誰もが知っているような著名プロジェクトが含まれている。
「このパッケージ、人気あるから大丈夫だろう」が通用しないのが、今のオープンソースの現実だと思います。

記事は、影響を受けた可能性がある人に次を勧めています。
pull_request_target ワークフローを audit するrotate は「鍵やトークンを使い回さず、新しいものに入れ替える」こと。
これ、面倒ですが本当に大事です。漏れたかどうか分からないなら、信じるより交換する。これが現場の現実です。
個人的には、今回の件でいちばん重要なのは “パッケージ名が有名かどうか”では安全を判断できない という点だと思います。
以前は「公式パッケージだから安心」「署名があるから安心」と考えがちでした。
でも今は、攻撃者が 配布の仕組みそのもの に入り込んでくる。
つまり、信頼の根拠がそのまま攻撃面になる時代です。
なので今後は、
といった“多層防御”がますます大事になるはずです。
面倒ですが、ここをサボると広く深くやられる。そんな事件でした。
Mini Shai-Hulud は、オープンソースの信頼チェーンを逆手に取った、かなり本格的な supply chain attack でした。
TanStack、Mistral AI、UiPath など有名どころまで巻き込まれ、しかも正規の署名や provenance を悪用していたのがやっかいです。
「便利な CI/CD が、そのまま攻撃経路にもなる」
この現実をかなりわかりやすく、しかも痛烈に示した事件だと思います。
参考: TanStack, Mistral AI, UiPath Hit in Fresh Supply Chain Attack