トップ›応用編›第16章
応用編第16章

依存ライブラリ経由の攻撃とslopsquatting

読む目安:約40分他人が作った部品が汚染される経路と、AIが生む新しい穴

あなたのアプリの大部分は、あなたのコードではありません。AIが書いた数千行の下に、他人が作った部品(ライブラリ、パッケージ)が何百個も積まれています。部品が汚染されれば、自分のコードがどれだけ正しくても穴が開きます。この章では、部品がどこから来て、どう汚染されうるかを実例で見たうえで、AIが存在しないパッケージ名を提案することから生まれる新しい攻撃、slopsquatting を扱います。

この章の学習目標

  • アプリが自分のコードと他人の部品でできていること、npm/pipがその部品をどこから取ってくるかを説明できるようになる
  • typosquatting、アカウント乗っ取り、悪意ある更新、依存の混同、そしてslopsquattingという攻撃の経路を、確認された実例とともに説明できるようになる
  • パッケージの実在と信頼性を自分で確かめ、ロックファイルと自動監視で守る手順を実行できるようになる

アプリは「自分のコード+他人の部品」でできている

ReactやNext.jsで作ったアプリのフォルダには package.json があり、「このアプリが使う部品の一覧」が書かれています。部品の実体は node_modules フォルダに入り、多くの場合、数百から数千個あります。指定したのは十数個でも、その部品がさらに別の部品を必要とし(推移的依存)、芋づる式に増えるからです。JavaScriptなら package.json と npm、Pythonなら requirements.txt と pip が、この役割を担います。

部品はレジストリ(npmjs.com、PyPI)という公開の倉庫から取ってきます。レジストリは誰でも、審査なしに、好きな名前で公開できる場所です。便利さの源泉であり、攻撃の入口でもあります。取引先マスタに誰でも業者を登録でき、登録されていれば支払いが通る状態に近いものです。

OWASP Top 10:2025では、この領域はA03「ソフトウェアサプライチェーンの不備」です。2021年版の「脆弱で古くなったコンポーネント」を、作る工程(ビルド、CI/CD)と配る工程(配布、更新)まで広げた項目で、コミュニティ調査では回答者のちょうど半数が1位に挙げました。論文では73件(6.16%)、28.00%のアプリに1件以上ありました。

部品が汚染される4つの経路(確認された実例)

「古い部品に既知の脆弱性がある」はA03のいちばん穏やかな形です。ここでは、部品そのものが悪意をもって汚染された経路を4つ、公式発表か主要メディアで確認できる実例とともに挙げます。

1. 名前の似た偽物(typosquatting)

人気パッケージと一字違いの名前で悪意あるパッケージを公開し、打ち間違えた人にインストールさせる手口です。「誰でも好きな名前で公開できる」ことをそのまま利用しています。slopsquattingの原型なので、後で詳しく扱います。

2. メンテナーのアカウント乗っ取り

2025年9月8日、npmで広く使われる chalk、debug など18個のパッケージが同時に汚染されました。合計で週に26億回以上ダウンロードされる基礎部品です。経路は、メンテナー(部品の管理者)に届いた、npm公式を装った「二要素認証の更新期限が迫っている」という偽メールでした。偽ログイン画面で盗まれた認証情報を使って悪意ある版が公開され、そのパッケージを使うWebアプリの利用者のブラウザで、暗号資産の送金先アドレスを攻撃者のものにすり替えるコードが動きました(BleepingComputer, 2025年9月8日)。あなたのアプリが chalk を直接使っていなくても、何かの部品の部品として入っていれば同じです。

3. 作る側に紛れ込んだ悪意ある更新

2024年3月29日、Red Hatは圧縮ライブラリ xz の5.6.0と5.6.1に、不正アクセスを可能にする悪意あるコードが含まれていると緊急警告を出しました(CVE-2024-3094)。難読化されたコードがサーバーへの遠隔ログイン(sshd)の認証に干渉する仕組みで、FedoraやDebianの開発版に届いていました。重いのは、外部からの侵入ではなく、2021年10月から2年以上にわたって善意の貢献者としてふるまい、共同メンテナーの立場を得た人物が入れたものだった点です(Russ Cox によるタイムライン, 2024年4月)。部品の信頼は、作者の信頼に乗っています。

4. 依存の混同(dependency confusion)

2022年12月25日から30日にかけて、PyTorchの開発版(nightly)をインストールした人が、悪意あるパッケージを取り込む事態が起きました。PyTorchが内部用に使っていた torchtriton という名前を、何者かが公開レジストリPyPIに同じ名前で登録し、インストール時にそちらが優先されたのです。PyTorchは依存を外し、pytorch-triton という新しい名前を自ら予約して再発を防ぎました(PyTorch公式フォーラム, 2022年12月31日)。

さらに2025年には、盗んだnpmの認証情報で自分自身を他のパッケージへ次々と公開する自己増殖型の「Shai-Hulud」が現れ、npmが止めるまでに500以上のパッケージ版に広がりました。OWASPはA03の原典でこれを「初の自己拡散型 npm ワーム」と呼んでいます。

slopsquatting:AIが生む新しい入口

ここからが、バイブコーディングに固有の話です。AIにコードを書かせると、AIは「この機能なら、このパッケージを使う」と判断して import 文を書きます。そのパッケージ名が実在しないことがあります。AIの幻覚(hallucination、もっともらしい嘘)が、パッケージ名にも起きるのです。

テキサス大学サンアントニオ校、バージニア工科大学、オクラホマ大学の研究チームは、16のコード生成モデルに57.6万件超のコードを書かせ、提案されたパッケージ名を調べました。約5件に1件が実在しないパッケージでした。商用モデルで5.2%、オープンソースモデルで21.7%。実在しない名前は205,474種類にのぼり、同じ質問を繰り返すと43%が再び同じ名前を出しました(Spracklen ほか, USENIX Security 2025)。

この「再現性」が問題です。攻撃者は、AIが繰り返し提案する存在しない名前を見つけ、その名前で悪意あるパッケージを先回りして登録できます。次に同じ名前を提案された誰かが、そのままインストールしてしまう。この手口を Python Software Foundation の Seth Larson 氏が slopsquatting と名づけ、Andrew Nesbitt 氏が広めました。

① AIが提案 実在しないパッケージ名を import に書く ② 攻撃者が先回り その名前で悪意ある部品を登録 ③ 次の利用者 AIが同じ名前を提案(43%が再出現) ④ そのままインストール 「実在するか」を誰も確かめない 守り:③と④の間で確かめる 公開日、ダウンロード数、作者、リポジトリの有無 提案の約5件に1件が実在しない(16モデル、57.6万件超のコード)。商用5.2%、オープンソース21.7%。
図16-1 slopsquattingの流れ。攻撃者はAIの「同じ間違いを繰り返す」性質を利用します。守りは、インストールの前に実在と信頼性を確かめることです。

第4章の失敗モードでいえば「⑥ 幻覚」(13件、1.1%)に当たります。論文で少ないのは、存在しないパッケージは動かず、公開に至らないからです。危険なのは、存在しない名前が「悪意ある実在の名前」に変わった瞬間からです。

守り方

部品の問題は、自分のコードを読んでも見つかりません。守りは「取り込む前に確かめる」「取り込んだものを固定する」「あとから見張る」の3段階です。

  • AIが提案したパッケージは、必ず実在を確かめる。npmjs.com または pypi.org で検索し、公開日(できたばかりでないか)、週あたりのダウンロード数(極端に少なくないか)、作者、ソースコードへのリンクの有無を見ます。人気パッケージと一字違いなら、本物のほうを使います。
  • 依存を増やさない。「このパッケージは本当に必要か、標準機能で済まないか」をAIに聞くだけで減らせます。部品が1つ減れば、推移的依存ごと数十個減ることがあります。
  • ロックファイルを保存する。npmの package-lock.json は「どの部品のどの版を使ったか」の記録です。Gitに入れておけば、次にインストールしても同じ版が入り、勝手に新しい(汚染されたかもしれない)版に変わりません。
  • 既知の脆弱性を自動で見張る。npm audit は手元で、Dependabotは継続的に、報告済みの脆弱性がないかを調べます(第12章)。通知が来たら、更新してから動作を確かめます。
  • 更新は少し待つ。2025年9月のnpmの事例で実害を出しうる時間帯は2時間半ほどだったと報じられています。公開直後の版に飛びつかず、数日置いてから更新すると、この種の事故の多くを避けられます。
AIへの頼み方(提案したパッケージの実在と信頼性を確かめさせる)
今回の変更で新しく追加した、または追加を提案したパッケージをすべて列挙してください。

それぞれについて、次を確認し、表にしてください:
1. 公式レジストリ(npmjs.com または pypi.org)に実在するか。実在しなければ「存在しない」と明記し、代わりの実在するパッケージを提案してください
2. 最初の公開日と最新版の公開日
3. 週あたりのダウンロード数のおおよその規模
4. 作者または管理組織と、ソースコードのリポジトリへのリンクの有無
5. 名前が似ている有名なパッケージがあるか(一字違い、ハイフンの有無など)。あれば、どちらが本物かを示してください
6. そのパッケージが本当に必要か。標準機能や既に入っている部品で代替できるなら、そのほうを提案してください

確認できなかった項目は「未確認」と書き、推測で埋めないでください。
package-lock.json(または版固定の要件ファイル)が更新されていることも確認してください。
補足:AIの回答も「確認」ではない AIが「実在する」と答えても、それ自体が幻覚である可能性があります。表の1〜4は、最後に自分の目でレジストリのページを開いて確かめてください。取引先の新規登録を申請書だけで通さず、登記や口座を照会するのと同じです。

SBOMとSLSA:第24章への予告

部品の一覧を正式な形式で出したものを SBOM(Software Bill of Materials、ソフトウェア部品表)と呼び、OWASP A03の原典も「一元的に生成・管理」を求めています。部品の「作られ方」自体を検証可能にする枠組みが SLSA(Supply-chain Levels for Software Artifacts)です。どちらも世界水準編の第24章で扱います。ここでは「部品表という考え方があり、自分のアプリにも作れる」と知っておけば十分です。

演習:依存パッケージの棚卸し

所要時間:約30分
  1. package.json(Pythonなら requirements.txt)を開き、直接指定している部品の数を点検ノートに書きます。node_modules の中のフォルダ数もおおよそ見ておきます。
  2. ロックファイル(package-lock.json など)がGitに入っているかを確かめます。なければAIに生成とコミットを頼みます。
  3. 直接指定している部品を1つずつ npmjs.com または pypi.org で検索し、公開日、ダウンロード数、作者、リポジトリへのリンクを見ます。見覚えのない名前、極端にダウンロードの少ないもの、有名パッケージと一字違いのものは「要確認」にします。
  4. AIに上の定型文を渡し、出てきた表と自分の確認を突き合わせます。食い違いは自分の目を優先します。
  5. Dependabot alertsと npm audit の未対応の通知があれば更新し、本番のアプリが正常に動くことを確かめます。
  6. 「本当に必要か」が怪しい部品は外せるか聞き、外したあとも動作確認をします。
注意:怪しいパッケージを「調べる」ためにインストールしない 要確認になった部品を、中身を見るために手元にインストールしないでください。インストールの瞬間に動くコードがあります。レジストリのページとリポジトリをブラウザで見るだけにとどめ、判断がつかなければ使わない側に倒します。

まとめ

  • アプリは自分のコードと、レジストリから取ってくる他人の部品でできている。レジストリは誰でも審査なしに公開できる。OWASP A03は部品だけでなく作る工程と配る工程を含み、論文では73件(6.16%)、28.00%のアプリにあった。
  • 汚染の経路は、名前の似た偽物、メンテナーの乗っ取り(2025年9月のnpm、18パッケージ、週26億回超のダウンロード)、中の人による悪意ある更新(2024年3月のxz)、依存の混同(2022年12月のPyTorch)。slopsquattingは、AIの提案の約5件に1件が実在せず、43%が再出現する性質を攻撃者が先回りして使う手口。
  • 守りは、取り込む前に実在と信頼性を自分の目で確かめる、依存を増やさない、ロックファイルで版を固定する、npm auditとDependabotで見張る、公開直後の版に飛びつかない。SBOMとSLSAは第24章で。

出典