マガジン

AIが勧めたnpmパッケージは実在するか:導入前に確かめる確認リスト

AIを使いこなす

Claudeで執筆し、GPTで自動校閲・修正しています。

手書きのチェックリストでパッケージ名を確認する様子
記事の内容をもとに制作したAI生成イメージです。実際の製品画面や検証結果の写真ではありません。

AIが勧めたnpmパッケージは、実在しないことがあります。実在していても、本来の目的のパッケージとは別物の可能性があります。そのため、npm install の前に、名前の存在確認だけでなく、公開元と更新状況、依存関係、インストール時に動くスクリプトまで見るのが安全です。 OWASPのSecure Coding with AI Cheat Sheetは、AIコーディングツールが存在しないパッケージ名を提案することがあり、攻撃者がその名前を先に登録する手口があると説明しています。AIが提案したパッケージ名を、検証せずに npm install や pip install へ渡さないことが対策の基本です。 この記事では、そのまま使える次の4点を渡します。 • AIに出させる情報を指定する依頼文 • 確認コマンド(説明用の例) • 項目別のチェック表 • 結果から導入可否を決める判断表

この記事の目次
  1. 「存在する」は合格条件ではない
  2. AIに渡す依頼文
  3. 確認コマンド(説明用の例)
  4. 導入前チェック表
  5. 判断表:どう扱うか
  6. 導入するときの手順
  7. 記録の書き方(説明用の例)

「存在する」は合格条件ではない

npm view パッケージ名 で情報が返れば、その名前は登録されています。npm公式の npm view の説明によると、このコマンドはレジストリのパッケージ情報を表示し、複数フィールドも指定できます。OWASPのNPM Security Cheat Sheetも、導入前に npm view で存在を確かめる方法を挙げています。ただし、これは入口の確認です。

  • 存在しない名前:見つからないというエラーになるのが通常です。AIの勘違いなので、その名前は使いません。
  • 存在するが別物の名前:実在の人気パッケージに似た綴りで、目的が違うものがあります。名前だけでは見抜けません。
  • 提案の直後に誰かが登録した名前:作成日が新しい、他に公開物がないといった形で表れます。

OWASPのAI向け資料は、疑わしい兆候として、ダウンロード数が非常に少ない、作成から30日未満、単一のメンテナで他にパッケージがない、を挙げています。下のチェック表もこの観点を土台にしています。数値の線引きは、各自のプロジェクトに合わせて調整してください。

AIに渡す依頼文

AIには、導入を判断させるのではなく、確認の材料を整理させます。AIの答えそのものは根拠になりません。根拠にするのは、レジストリや公式ドキュメントで人が見た情報です。

text
次の目的で使えるnpmパッケージ候補を挙げてください。
目的:CSVを読み込んでJSONに変換する(Node.js、サーバー側)

条件:
- インストールコマンドは出さないでください
- 各候補について「パッケージ名(scopeを含め正確に)」
  「公式ドキュメントのURL」「そのURLを知っている根拠」を書いてください
- 自信がない名前には「未確認」と明記してください
- 名前が似ている別パッケージがある場合は、その名前も書いてください

返ってきたURLや名前は、そのまま信じず次の確認に回します。公式ドキュメントのリンクが開けない、またはそのページに同じパッケージ名が載っていない場合は、その時点で保留です。

確認コマンド(説明用の例)

次のスクリプトは、確認用に組んだ説明用の例です。この記事の執筆中には実行していません。手元のNode.jsとnpmのバージョンで、一度動作を確かめてから使ってください。出力の表示形式も環境で変わる場合があります。

sh
#!/bin/sh
# 使い方: sh check-pkg.sh パッケージ名
PKG="$1"
[ -z "$PKG" ] && { echo "パッケージ名を指定してください"; exit 1; }

echo "== 1. 存在と基本情報 =="
npm view "$PKG" name version license description || exit 1

echo "== 2. 日付(作成・最終更新) =="
npm view "$PKG" time.created time.modified

echo "== 3. 公開元 =="
npm view "$PKG" maintainers repository.url homepage

echo "== 4. 依存関係 =="
npm view "$PKG" dependencies

echo "== 5. スクリプト(install系を探す) =="
npm view "$PKG" scripts

出力は、そのままAIに貼って「次の表に当てはめて整理して」と頼めます。このとき、社内パッケージ名や非公開リポジトリのURLが混ざっていないか確認してください。

導入前チェック表

  • 名前の綴り、見る場所:AIの回答と公式ドキュメントの表記を一文字ずつ比較。scope(@組織名/)の有無も見る、止まる兆候:公式ドキュメントと綴りが違う、ハイフンや数字だけ違う
  • 公式側からの裏付け、見る場所:使いたいライブラリの公式サイトやREADMEに、その名前のインストール手順があるか、止まる兆候:公式側に名前の記載がない
  • 作成日・更新状況、見る場所:time.created、time.modified、止まる兆候:作成から日が浅い、長く更新がなく目的の環境に合わない
  • 公開元、見る場所:maintainers、repository.url、homepage、止まる兆候:リポジトリURLがない、リポジトリが別名・空、メンテナが単独で他の公開物がない
  • 依存関係、見る場所:dependencies、止まる兆候:小さな機能なのに依存が多い、知らない名前が混じる
  • インストール時スクリプト、見る場所:scripts の preinstall・install・postinstall、止まる兆候:目的に関係ない処理、外部ダウンロード、難読化された記述
  • 利用実績、見る場所:npmjs.comのパッケージページなどで利用状況を見る、止まる兆候:利用がごくわずかで、他の確かな情報もない
  • ビルド元の記録、見る場所:provenance(出所の証明)が付いているか、止まる兆候:付いていないこと自体は不合格ではない

provenanceについて、npm公式はprovenance statementsの説明で、ビルド元を示すものであって安全性を保証するものではないとしています。付いていれば確認材料が増えますが、それだけで採用してはいけません。

依存関係に知らない名前があるときは、その名前にも同じスクリプトを実行します。依存の先まで全部追う必要はなく、まず直下の依存を確認する程度でも、見落としはかなり減ります。

判断表:どう扱うか

次の表は、編集上の目安です。npmの公式仕様ではありません。

  • npm view で見つからない、扱い:不採用。AIに別の候補を出させるか、公式ドキュメントから探す
  • 存在するが、公式側に記載がない、扱い:保留。公式の案内にあるパッケージ名を探し直す
  • 公式側に記載があり、公開元・更新状況・依存関係に不審点がない、扱い:導入候補。次の導入手順へ進む
  • 作成が新しい、公開元が不明、install系スクリプトが目的に合わない、扱い:不採用または保留。別の定番を探す
  • 判断がつかない、扱い:導入しない。使う目的を小さな自作コードで代替できないかも検討する

導入するときの手順

確認を通ったパッケージも、最初は次のようにスクリプトを無効にして入れると安全側に寄ります。OWASPのNPM資料は、サードパーティのスクリプト実行を抑える手段として --ignore-scripts と、.npmrc への ignore-scripts=true の設定を挙げています。

sh
npm install パッケージ名 --ignore-scripts

そのうえで、次を確認します。

  1. package.json と、ロックファイルの変更差分が、想定したパッケージだけか見る
  2. 動作確認が通ったら、ロックファイルも一緒にコミットする
  3. 他の環境やCIでは、ロックファイルに沿って入れる npm ci を使う(OWASPも、ロックファイルと食い違えば中断する点を利点としています)

なお、スクリプトを無効にすると、ネイティブ拡張のビルドなどが必要なパッケージは動かない場合があります。その場合は、scripts の中身を読んで納得できてから、人が判断して有効化してください。

記録の書き方(説明用の例)

後から見返せるよう、判断結果を短く残しておきます。次の例は架空で、実在のパッケージの調査結果ではありません。

text
候補: example-csv-tool(説明用の例)
公式ドキュメントでの記載: あり(READMEのインストール手順と一致)
作成日 / 最終更新: 記録する
公開元: メンテナ名・リポジトリURLを記録
依存関係: 直下の依存を列挙、不明な名前は個別に確認
install系スクリプト: なし
判断: 導入候補 → --ignore-scripts で導入し、ロックファイルをコミット
確認日: 日付を記録

AIの提案を毎回この形で記録しておくと、「どの名前を、何を根拠に入れたか」を後から説明できます。

出典・参考資料