スロップスクワッティング — AI が言った npm install は、本物とは限らない

スロップスクワッティングは、AI が「存在しないパッケージ名」を提案し、攻撃者がその名前で悪意あるパッケージを先回りして登録しておく攻撃。2026年の研究では主要 AI モデルが提案した名前の約4.6〜6.1%が実在せず、同じ質問を10回繰り返すと43%の架空名が毎回同じ。攻撃者は「AI が言いそうな名前」を予測して先に登録できる。AI が書いた install は「提案」であって「検証済み」ではない。実行前に公式ページで4つ見る。頼み方と確かめ方。

動画で見る

結論から

スロップスクワッティングは、AI が「存在しないパッケージ名」を提案し、攻撃者がその名前で本物そっくりの悪意あるパッケージを先回りして登録しておく攻撃です。AI が npm install react-form-validator-pro のような命令を書き、あなたがそのまま実行すると、攻撃者のコードがあなたのパソコンと本番環境に入ります。2026年の研究では、主要な AI モデルが提案したパッケージ名の 約4.6〜6.1%が実在しないもので、同じ質問を10回繰り返すと43%の架空名が毎回同じ名前で再登場しました。つまり、攻撃者は「AI が言いそうな架空の名前」を予測して、先に登録できます。

この記事で伝えたいのは、この一点だけです。AI が書いた `npm install` / `pip install` は「提案」であって「検証済み」ではない。実行する前に、そのパッケージが本物か(公式か・ダウンロード数があるか・いつからあるか)を、1回だけ見る。 AI は名前を間違えても「動く」ように見せるのが上手で、間違いに自分では気づきません。

  • 何が起きるか:AI が実在しないパッケージ名を提案 → 攻撃者がその名前で悪意あるパッケージを登録済み → install した瞬間に、環境変数(API キー・DB パスワード)が外部に送られる
  • なぜ:AI は「それっぽい名前」を作るのが得意で、実在確認はしない。架空の名前は毎回似ているので、攻撃者が予測できる
  • 直す:install の前に、npm / PyPI の公式ページで「ダウンロード数」「公開日」「作者」を見る。AI に「このパッケージの公式 URL と週間ダウンロード数を示して」と頼む。package.json にある見慣れない名前を棚卸しする
  • 確かめる:自分のプロジェクトの package.json / requirements.txt の依存を AI に列挙させ、それぞれの公式ページとダウンロード数を確認する。週間ダウンロードが数十件・公開が最近・作者不明、が揃ったら ✗

動画版(約2分半)は本文の上に埋め込んであります。

① 何が起きるのか:AI が言った名前が、存在しない

例として、AI に「フォームのバリデーションを付けて」と頼んだとします。AI はこう返します。

「react-form-validator-pro を使います。npm install react-form-validator-pro を実行してください」

もっともらしい名前です。でも、このパッケージは存在しません。AI が、実在する react-hook-form や validator などの記憶を混ぜて、それっぽい名前を作ったのです(これを「ハルシネーション」と呼びます)。

ここまでなら「インストールできない」というエラーで終わります。問題は、その先です。攻撃者は、AI が架空の名前を作る癖を知っています。AI に何度も同じ質問をして、繰り返し出てくる架空の名前を集め、その名前で悪意あるパッケージを先に npm に登録しておく。すると、次に AI がその名前を提案したとき、npm install は成功します。中身は、あなたの .env(API キー・DB パスワード)を攻撃者のサーバーに送るコードです。

これがスロップスクワッティングです。「タイポスクワッティング」(人間の打ち間違いを狙う)の AI 版で、2025年に名前が付きました。

研究の数字を挙げます。2026年に約20万件の AI 出力を調べた研究では、主要5モデルが提案したパッケージ名の 4.62〜6.10%が実在しないものでした。2025年の USENIX Security での研究では、商用モデルで平均 5.2%、オープンソースモデルで 21.7%。そして、同じ質問を10回繰り返すと、架空の名前の 43%が毎回同じで、58%が複数回登場しました。攻撃者にとって「予測できる」ということです。実際に、2026年4月時点でまだ誰も登録していない架空の名前が、PyPI と npm あわせて 53件見つかっています。

スロップスクワッティング:AI が提案した架空のパッケージ名を、攻撃者が先に登録する

② なぜ起きるのか:AI は「それっぽい」を作り、確認はしない

AI は、学習した膨大なコードから「この文脈なら、こういう名前のパッケージがありそう」と予測して文章を作ります。実在するかどうかを npm に問い合わせてはいません。だから、実在するものと架空のものが、同じ自信で出てきます。

さらに、AI コーディングツール(Cursor・Claude Code・Copilot)では、AI が npm install を提案するだけでなく、そのまま実行することがあります。人間が名前を目にする前に、インストールが終わっている。動作確認で「動いた」なら、誰も名前を見返しません。

攻撃者側の手順は単純です。①AI に人気の質問(「認証を付けて」「PDF を生成して」)を繰り返し投げる。②繰り返し出てくる架空の名前を集める。③その名前で、本物そっくりの説明文を付けた悪意あるパッケージを登録する。④待つ。

AI はどう書くか。 AI に「このパッケージは本物?」と聞けば、多くの場合は正直に「確認できません」と答えます。でも、聞かなければ確認しません。そして AI 自身が install を実行する設定なら、聞く暇がありません。防ぐのは、AI ではなく、実行前の1回の確認です。

③ どう直すのか:AIに「公式 URL とダウンロード数」を頼む

以下をそのまま AI ツールに貼ってください。

「このプロジェクトの package.json(および requirements.txt など)に含まれる依存パッケージをすべて列挙し、それぞれについて、①公式レジストリ(npmjs.com / pypi.org)の URL、②週間ダウンロード数、③最初の公開日、④GitHub リポジトリの有無、を表にしてください。週間ダウンロード数が1,000未満、または公開日が直近3か月以内、または GitHub リポジトリが無いものは、目立つように印を付けてください。今後、新しいパッケージを追加提案するときは、必ず①〜④を添えて、私が確認してからインストールしてください。」

ポイントは、「今後も①〜④を添えて」。1回の棚卸しで終わらせず、AI の提案の形式を変えます。AI ツールに「install を自動実行しない」設定があれば、それも有効にします。

④ 直ったかを確かめる:見慣れない名前を、公式で引く

  • `package.json` を開き、知らない名前を1つ選んで、https://www.npmjs.com/package/<名前> を開く。週間ダウンロード数・公開日・GitHub リンクを見る
  • ダウンロードが数十〜数百件で、公開が最近で、GitHub が無いなら、そのパッケージを使っている理由を AI に聞く。代替の有名パッケージに置き換える
  • `npm audit` / `pip-audit` を実行する(既知の脆弱性の確認。→ 依存パッケージの記事)。スロップスクワッティングの新種は「既知」に載る前なので、①の目視が要る
  • AI ツールの設定で、コマンドの自動実行が有効になっていないかを確認する
  • 分からなければ、AIに「依存パッケージのうち、週間ダウンロード1,000未満のものを一覧にして」

自分で直せないとき:エンジニアに送る一文

「AI が提案したパッケージをそのままインストールしています。package.json の依存に、実在性・ダウンロード数・作者が怪しいものが無いか棚卸しをお願いします。あわせて、今後のインストール前チェックの手順も決めたいです。」

よくある質問

有名なパッケージ(React・Next.js・Supabase)を使っていれば大丈夫ですか。

その4〜6本は大丈夫でも、それらが依存する数百本や、AI が「便利だから」と足した小さなパッケージが問題です。package.json の中で、自分で名前を説明できないものを確認してください。

AI が提案した名前が実在すれば、安全ですか。

実在しても、乗っ取られたパッケージ(→ 依存パッケージの記事の Shai-Hulud)や、名前が1文字違いの偽物(タイポスクワッティング)があります。「実在する」に加えて「ダウンロード数が多い」「長く公開されている」「GitHub がある」を見ます。

Python でも同じですか。

同じです。研究では PyPI の方が架空名の未登録が多く(53件中41件)、狙われやすい状態でした。pip install も同じ確認をします。

この穴が塞がれば、依存パッケージは安全ですか。

「架空の名前」は防げます。「本物のパッケージが乗っ取られる」「本物に脆弱性が見つかる」は別の話で、次の記事(依存パッケージの脆弱性)で扱います。