コード生成モデルは、存在しないパッケージ名を予測可能な形でハルシネーションする(コードの19,7%、しかも名前の43%が繰り返される)ため、攻撃者が悪意あるペイロードと共に先回りして登録できる。防御策は、AIが提案したあらゆるパッケージが実在し正当であることをインストール前に検証することだ。
金物店でネジを持ってきてほしいと助手に頼んだと想像してほしい。どれが正解か分からないのを認める代わりに、助手は完璧にもっともらしく聞こえるブランド名を発明する。「クラフテンM8ネジ」と。あなたは信じ込んでそれを買いに行く。ところが、まさにその発明を先回りして、誰かがすでにその名前で店を開き、箱を爆発物で満たしていたのだ。これをソフトウェアに移し替えたものには、2025年以来、名前がついている——スロップスクワッティング(slopsquatting)だ。あなたのAIが存在しないライブラリを発明し、攻撃者があなたより先にそれを登録して悪意あるコードを仕込む。プログラミング支援の時代が持ち込んだ、最もエレガントで静かなサプライチェーン攻撃のベクトルであり、あなたのチームでその存在を知る者はほとんどいない。
ハルシネーションはもう笑い話ではなく、攻撃対象領域になった
何年ものあいだ、私たちはAIのハルシネーションを愉快な小話として扱ってきた。モデルが引用や、データや、日付を発明する。煩わしいが、無害だ。ところがコードとなると、ハルシネーションはその性質を変える。モデルが`requests`の代わりに`import requestz`と書いたり、一度も存在しなかった`pandas-utils-pro`を発明したりするとき、それはジョークを飛ばしているのではない。誰か他人が換金できる小切手にサインしているのだ。偽の引用とは違い、パッケージ名は住所だからだ。そして住所は占有できる。ハルシネーションがnpmやPyPIに登録可能な郵便住所を持った日、それはスタイル上の誤りであることをやめ、扉に変わった。
硬い数字:ほぼ5つに1つのコード断片が幽霊パッケージを提案していた
USENIX Security 2025で発表された研究が、これを産業規模で測定した。16の異なるモデルによって生成された223万件のコードサンプルだ。その結果は、あなたがモニターに貼っておくべきものだ——サンプルの19,7%が、少なくとも1つのハルシネーションされたパッケージ、つまり単に存在しないものを含んでいた。そしてモデル系統による偏りは凄まじい。オープンソースのモデルは21,7%の確率でパッケージを発明したのに対し、商用モデルは5,2%だった。翻訳すると、モデルが依存関係を差し出してくるほぼ5回に1回は、存在しないものを差し出しているということだ。それに、「AIが書いたのだから、存在するだろう」という盲信のもとで日々実行される数百万の`pip install`と`npm install`を掛け合わせれば、そこに攻撃対象領域が生まれる。
本当に危険なのは発明することではなく、いつも同じものを発明することだ
もしハルシネーションがランダムなノイズだったなら、この攻撃は成立しない。攻撃者は1つを当てるために何百万もの名前をでたらめに登録しなければならないからだ。これを現実の問題に変える発見は別のところにある——ハルシネーションされた名前の43%が、すべての実行で再出現するのだ。ノイズではない、署名だ。モデルは同じプロンプトに対して、同じ偽の名前を何度も何度も発明する傾向がある。これは攻撃者にとって金鉱だ。モデルが何を発明するかを観察し、繰り返される名前を拾い、悪意あるペイロードと共にそれを登録して、待つだけでいい。何かをハッキングする必要はない。罠を仕掛けたのはあなた自身であり、あなた自身のエージェントが、あなたのビルドの権限でそれをインストールする。Python Software FoundationのSeth Larsonが、このパターンに命名した——スロップスクワッティング、タイポスクワッティングのいとこだ。ただし誤りを犯すのはあなたの指ではなく、あなたのモデルなのだ。
なぜエージェント型プログラミングはリスクを抑えるどころか増幅させるのか
提案の中に`import fastapi-turbo`を見た人間の開発者は、たいてい眉をひそめる。「それ、存在するの?」と。自律エージェントは眉をひそめない。あなたが「動くようにしろ」と言い、エージェントは失敗するimportにつまずき、その訓練された反射は解決することだ。`install`を実行し、パッケージが存在すれば(攻撃者が登録したので存在する)、摩擦なくインストールして先へ進む。エージェント型プログラミングを魔法にするループ——試す、失敗する、直す、進む——こそが、私たちを守っていた唯一の防壁、人間の疑いを飛び越えるものなのだ。エージェントが自律的であるほど、ハルシネーションと`install`のあいだにある目は少なくなる。検証なき自律はスピードではない。ヘッドライトを消したまま断崖へ向かうスピードだ。
教訓:AIの時代において、名前への信頼はセキュリティ上の決断である
あなたが持ち帰り、共有できるメンタルフレームはこうだ——AIが提案したパッケージ名は事実ではなく、仮説である。そして、あなたのビルドの権限でコードを実行しようとするあらゆる仮説は、後ではなく事前に検証されるに値する。具体的な行動は一文に収まる——モデルが提案した依存関係をインストールする前に、そのパッケージが本当に存在すること、それがあなたの思うものであること、そして先週ゼロの履歴で生まれたものではないことを確認せよ。ハッシュを固定したlockfile、依存関係のallowlist、そして「このパッケージは何年もの歴史とダウンロードがあるのか、それとも火曜日に現れたのか?」への2秒の一瞥が、この攻撃を完全に無効化する。AIのファイアウォールは要らない。要るのは、モデルの出力を聖典として扱うのをやめることだ。ちなみに、これと同じ規律が、デモを製品から分けるものでもある——それについては27%の数学で語っている。
私たちの見方
NeuralOSでは、ある居心地の悪い公理から出発する——AIは輝かしい協力者であると同時に、ときおり嘘をつく者であり、その両方を同時に想定して設計しなければならない。だからこそ私たちは、セキュリティを最後に貼り付ける層としてではなく、その上に築いていく地面として考える。その地面のいくつかのピースはすでに手触りのあるものだ。シークレットはすべてのログで値ごとに編集(redact)され、認証情報はモデルに決して露出されないテナントごとに暗号化されたVaultの中で生きている。他のものは宣言された方向性であって、果たされた約束ではない。同じ路線で私たちはSentinel——バグが本番に届く前に捕まえるオープンソースのコードセキュリティの守護者——を作り、無償で提供した。モデルが名前をハルシネーションするのを防ぐことは、私たちにはできない——誰にもできない、それはシステムの物理だ。だが私たちが追い求めているのは、ピースごとに、そしてすでに存在するものとまだ道半ばのものについて正直でありながら、そのハルシネーションとあなたのビルドのあいだに堀を築くことだ。エージェントがもはや持たない疑いを、プラットフォームがあなたの代わりに持っていくように。なぜなら、プログラマーでなくともAIで構築する時代において、あなたの優位はより速く信頼することではないからだ——検証があなたの善意だけに依存しないこと、それが優位なのだ。