AIが持ち込む部品の危険

AIは、存在しない部品の名前を、もっともらしく、繰り返し出す。その名前を先に登録されると、入れる命令がそのまま悪いコードを引き込む。部品を足す差分は、名前が実在し、意図した物であることを確かめてから入れる。

数字は Spracklen らの論文 USENIX Security 2025 によります[1]。OWASP Top 10 for LLM Applications 2026 は、この型を LLM04:2026 Supply Chain で、登録された名前を先回りで取る slopsquatting として扱います[2]。2026年11月時点。

要点

  • 16のモデルで作った576,000件のコードで、勧められた部品の19.7%が存在しなかった。
  • 同じ問いを10回繰り返すと、存在しない名前の43%は10回とも出た。繰り返し出る名前は、先に登録できる。
  • 名前の多くは実在の部品の打ち間違いではない。打ち間違いを探す検出では拾えない。
  • 守りは、足す差分で止めて確かめる、ロックとハッシュで固定する、出どころを確かめる、公開から日の浅い版と導入時のスクリプトを避ける。
  • 出どころの証明は、悪いコードが無いことの証明ではない。

攻撃が通る道筋

AIが出した存在しない名前を攻撃者が先に登録し、次に同じ名前が出たときに導入され、導入時か読み込み時に悪いコードが動く 1 AIが名前を出す まだ存在しない 観測する 2 攻撃者が登録 同じ名前で公開の登録所へ 3 また同じ名前 別の利用者、別の日 待つ 4 導入 人か、AIの道具が直接 5 悪いコードが動く 導入時のスクリプト、読み込み時 4の前で止める 足す差分を人が見る。登録所で実在と履歴を見る 導入時のスクリプトを止める
図1 存在しない部品の名前が、悪い部品の導入になるまで

AIのコーディングの道具では、4の導入を人ではなくAIが命令で行える。人は名前を見ないまま、依存の定義とロックファイルの差分だけが残る。

論文の数字

項目結果
対象16のモデル、Python と JavaScript、576,000件のコード
存在しない部品の割合全体で19.7%。商用のモデルの平均で5.2%以上、公開のモデルで21.7%
存在しない名前の数重なりを除いて205,474
繰り返し同じ問いを10回したとき、43%は10回とも出て、39%は一度も再び出なかった
実在の名前との近さPython の存在しない名前のうち、最も近い実在の名前との編集距離が1か2のものは13.4%。6以上が48.6%
別の言語Python の存在しない名前の8.7%は、JavaScript では実在する部品だった

出典はいずれも同じ論文[1]。著者は、悪用を避けるため、存在しない名前の一覧を公開していない。読み取れることは2つある。繰り返し出る名前は、攻撃者が観測して先に登録できる。打ち間違いに近い名前を探す検出では、半分近くを拾えない。

OWASP の2026年版も、コーディングの助けをするAIが存在しない名前を大量に出し、攻撃者が先に登録することで、確かめずに入れた依存が悪いコードに解決されると書く[2]。

守り方

足す差分で止めて確かめる

根本は、新しい部品が入る時点を人が必ず通ることにする。

.claude/settings.json 部品を入れる命令は毎回聞かせる

{
  "permissions": {
    "ask": ["Bash(npm install *)", "Bash(npm i *)", "Bash(pnpm add *)", "Bash(pip install *)", "Bash(uv add *)"]
  }
}

規則は命令の書き方に当たるので、別の書き方の導入はすり抜け得る[3]。最後の網は、依存の定義とロックファイルの差分を人が読むことである。

確かめること見る所
意図した物か使いたいライブラリの公式の文書が示す名前と一致するか。似た名前で別物でないか
実在して育っているか登録所の公開日、版の履歴、管理者、ソースのリポジトリへのリンク
要るか標準の機能や、既に入っている部品で足りないか
導入時に何が動くかpreinstall、install、postinstall のスクリプトの有無

固定する

  • npm ci は既存のロックファイルを必須とし、package.json と食い違えばロックを更新せずに誤りで終わる。package.json とロックを書き換えない[4]。CIはこれで入れる。
  • pip は --require-hashes でハッシュの照合を強制し、全部の部品にハッシュを求める。ソースの配布を拒む --only-binary :all: との併用が勧められている[5]。
  • GitHub Actions の外部のアクションは、完全なコミットのSHAで固定する[6]。AIが書くワークフローは版のタグを使いがちなので、差分で見る。

出どころを確かめる

npm の provenance は、部品がどこでどう作られ、誰が公開したかを公に示し、npm audit signatures で照合できる。ただし npm の文書は、部品に悪いコードが無いことを保証しないと明記している[7]。存在しない名前を先に登録した者も、自分のリポジトリから正しく出どころを付けて公開できる。出どころは、誰の物かを確かめる手段で、安全の証明ではない。

日の浅い版と、導入時のスクリプトを避ける

  • pnpm の minimumReleaseAge は、公開から指定の分数が過ぎるまで、その版を入れない。2026年11月時点の文書で既定は1440分[8]。
  • pnpm は、allowBuilds に載せていない依存の導入時のスクリプトを既定で許さず、strictDepBuilds の既定で導入を誤りで終える[9]。
AIの道具そのものも部品である

MCPのサーバー、エディタの拡張、AIの道具の追加機能も、外から持ち込む部品である。OWASP の2026年版は、MCPのサーバーと外部の道具の部品を、版を固定し、署名を確かめ、道具の説明に隠れた命令が無いか調べるよう求める。版を固定しても、固定した版に入った悪いコードと、版を変えずに書き換えた説明は防げないとも書く[2]。説明の問題は読ませた文書に紛れた命令で扱う。

参照

  1. We Have a Package for You! A Comprehensive Analysis of Package Hallucinations by Code Generating LLMs Spracklen ほか。USENIX Security Symposium 2025
  2. OWASP Top 10 for LLM Applications 2026 OWASP GenAI Security Project、公式ページの日付は2026年8月3日。LLM01:2026、LLM04:2026、LLM07:2026
  3. Best practices for Claude Code Anthropic
  4. npm-ci npm Docs
  5. Secure installs pip documentation
  6. Secure use reference GitHub Docs
  7. Generating provenance statements npm Docs
  8. Dependency resolution settings pnpm
  9. Build settings pnpm