supply-chain-security について
supply-chain-securityは、マニフェスト、ロックファイル、インストールスクリプト、依存関係の変更を調べるモデル支援型の依存レビュー スキルです。ツールやパッケージを実行せずに、深刻度と具体的な修正案を添えてサプライチェーン上のリスクを報告します。
主な機能
- 01依存関係のマニフェストとロックファイルの確認
- 02追加・変更されたパッケージの優先確認
- 03インストール時スクリプトとビルドフックの調査
- 04難読化コードと秘密情報へのアクセスの検出
- 05情報流出と永続化動作の特定
- 06深刻度と修正案の報告
活用シーン
- 01プルリクエストの依存関係変更のレビュー
- 02未確認パッケージをインストール前に調査
- 03不審なインストールスクリプトの調査
- 04パッケージファイルがある依存関係の出所評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ superagent-ai/ skills --skill supply-chain-securityインストール後、Claude Code で/supply-chain-securityを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/checklist.mdecosystems.mdpatterns.md詳細
サプライチェーンセキュリティスキャナー
このスキルは、モデルを依存関係レビュー担当にします。マニフェスト、ロックファイル、インストールスクリプト、依存関係の差分を読み、検出パスを順に確認し、各サプライチェーンリスクについて、深刻度と具体的な修正方法を報告します。インストールするツールも、実行するパッケージも、問い合わせるレジストリもありません。分析とは、モデルがディスク上の内容と差分を読むことです。
依存関係とは、自分で書いたわけでもレビューしたわけでもないのに、プロジェクト内で完全な権限を持って実行されるものです。防御側の問題は、依存関係が正規のものに見えることです。npm史上最大の侵害では、フィッシングでメンテナーのアカウントを乗っ取った攻撃者が、週間ダウンロード数20億回のchalkとdebugを通じて攻撃しました。また、Shai-Huludワームは、盗んだトークンを使って約800個のパッケージを再公開し、バックドアを仕込みました。人気があっても安全とは限りません。依存関係を追加または変更したときこそ、このスキルでレビューすべきタイミングです。
メンタルモデル
新規または変更された依存関係は、見知らぬ相手のコードを2回実行します。まずインストール時(ライフサイクルスクリプトが、コードを1行もレビューする前に、開発者のノートパソコンやCIランナーで実行されます)。次に実行時(アプリ内で、ユーザーのブラウザーやサーバー上で実行されます)。安全性を判断する鍵は、次の2つの問いです。
- 正体 — 意図したパッケージであり、想定した公開者が公開したものですか? タイポスクワッティング(人気の名前のつづり間違い)、スロップスクワッティング(AIが幻覚で生成したもっともらしい名前を、攻撃者が先回りして登録すること)、依存関係/名前空間の混乱(内部名が公開レジストリで取得されること)、メンテナーアカウントの乗っ取り(信頼された名前と盗まれたトークン)によって脅かされます。
- 振る舞い — そのライブラリが掲げる用途では理由のない動作をしていませんか? 特にインストール時の動作に注意してください。悪意あるライフサイクルスクリプト、難読化されたペイロード、認証情報の収集、外部への情報流出、永続化、自己拡散によって脅かされます。
インストール時のフックは最大の標的です。 コードレビューが行われる前に、開発者のマシンやCIランナーで、環境全体とトークンにアクセスできる状態で実行されます。そのため、主要なワームはすべて(Shai-Hulud、nxのs1ngularity攻撃、2026年6月のbinding.gypキャンペーンなど)、インストール時を狙っています。多くはpreinstall/postinstallを利用しますが、binding.gypワームは、偽のネイティブビルド中にnode-gypを使って任意のシェルコマンドを実行させることで、これらのフックを完全に回避します。パッケージが完全に正常に動作していても、インストールした瞬間にマシンを乗っ取られる可能性があります。
パッケージの正体を確認できない場合、またはインストールスクリプトの動作を説明できない場合は、信頼できないものとして扱い、フラグを立ててください。 偽陽性のコストは、PRが保留になり、数分かかることです。偽陰性のコストは、マシンとCI上のあらゆる認証情報に加え、ワームの次の拡散経路として再公開される自分のパッケージです。この非対称性を、以下のあらゆる判断の基準としてください。
スキャン手順
以下のパスを順番に確認してください。パス0ではレビュー対象と新たに追加されたものを特定します。ここを省略しないでください。
パス 0:レビュー対象の範囲を把握する
エコシステムと、実際にどこまで確認できるかを知らなければ、依存関係を評価できません。
- エコシステムとファイルを特定します。
package.jsonとロックファイル(npm/pnpm/yarn)、requirements.txt/pyproject.toml/poetry.lock/uv.lock(PyPI)、go.mod+go.sum、Cargo.toml+Cargo.lock、Gemfile+Gemfile.lock、pom.xml/build.gradle、.csproj/packages.lock.json、composer.json+composer.lockを確認します。それぞれでインストールフック、バージョン固定、整合性、スコープがどこに記述されているかは、references/ecosystems.mdを参照してください。 - 新規または変更されたものを探します。 PR では、マニフェストとロックファイルの差分が対象です。新たに追加されたパッケージ、バージョンの更新、新しい推移的依存関係、新しいインストールスクリプトなどを確認します。それぞれについて、直接依存か推移的依存か、新規パッケージかバージョン変更か、シークレットを保持する環境(公開トークンのある CI、クラウド認証情報を持つ開発者のノート PC など)でインストールが実行されるかを記録します。
- どこまで確認できるかを記録します。 パッケージのソースがディスク上にある場合(
node_modules/、ベンダー提供、展開済み tarball など)は、インストールスクリプトとペイロードを直接確認できます。必ず確認してください。マニフェストに名前とバージョンしかない場合、確認できるのは識別情報と衛生状態に限られます。その旨を明記し、締めくくりのセクションにある確認用コマンドを推奨してください。
パス 1:識別 — 意図したパッケージか?
動作を調べる前に、その名前が想定した提供元に解決されることを確認します。
- タイポスクワッティング。 人気パッケージの名前と、わずかな編集距離またはキー入力距離しか違わない名前です。例:
crossenv↔cross-env、reqeusts↔requests、lodahs↔lodash、electorn↔electron。有名なパッケージから、文字の入れ替え・欠落・重複が 1 つだけ異なる名前の依存関係があれば、注意してください。 - スロップスクワッティング(AI が幻覚した名前)。 LLM が提案するパッケージ名のおよそ 5 件に 1 件は存在せず、同じ幻覚が繰り返されるため、攻撃者は人気のある名前を先回りして登録し、マルウェアを仕込みます。もっともらしいものの、なじみのない「ヘルパー」系の名前(
flask-gpt-helper、auth-helper-pro、py-openai-utils、easy-requestsなど)には注意してください。AI の提案で依存関係を追加した場合は、インストールする前に、まったく同じ名前で実際にパッケージが存在することを確認してください。幻覚による import をインストールにつなげないでください。 - 依存関係/名前空間の混同。 内部用に見える非スコープ付きの名前(
internal-、corp-、company-、製品コードネームなど)は乗っ取られるおそれがあります。攻撃者が同じ名前を公開レジストリに、より高いバージョンで公開すると、解決時にそちらが選ばれます。また、組織のスコープとほとんど同じスコープ(@acme-corpと@acmeなど)にも注意してください。対策は、コミット済みの設定でプライベートレジストリを指定して、スコープ付きの名前を固定することです。references/patterns.mdを参照してください。 - アカウント乗っ取りの兆候。 長期間安定しているパッケージが、突然不自然なバージョンを公開する、メンテナーが変わる、これまでなかったインストールスクリプトを追加する、またはパッケージの目的と無関係なファイルを差分に追加する場合です。特に、ネイティブコードを一度も提供したことのないパッケージに
binding.gypや、ルートに数 MB のindex.jsが追加されている場合は要注意です。chalk/debug、nx、Shai-Hulud、binding.gyp ワームはいずれも、フィッシングまたは盗難されたトークンを利用し、信頼された名前を通じて侵入しました。スタイリングライブラリにpreinstallと新しいファイル 2 つが追加される差分は警戒すべき形です。純粋な JavaScript ライブラリにbinding.gypとindex.jsが追加される差分も同様です。
パス 2:インストール時の実行 — 最重要ポイント
すべてのライフサイクルスクリプトを確認します。npm の場合は、package.json の scripts にある preinstall、install、postinstall、prepare を確認します。ほかの場所での同等のものとして、setup.py/PEP 517 のビルドフック(PyPI)、ネイティブの extconf.rb(RubyGems)、build.rs(Cargo)があります。preinstall は最も強い兆候です。Shai-Hulud 2.0 は、検査ツールが動作する前に実行されるよう、意図的にここへ移動しました。
存在する場合は、binding.gyp も確認します。npm はこれを検出すると、ネイティブアドオンだと想定してコンパイルするために node-gyp を呼び出します。これはライフサイクルフックではないため、ignore-scripts=true の場合でも実行されます。2026 年 6 月の binding.gyp ワームは、package.json の scripts をクリーンなままにし、sources 配列内のシェル展開を悪用する約 100 バイトの binding.gyp に実行処理を隠しています。
// [P0] binding.gyp worm — node-gyp runs arbitrary shell during "compile"
{
"targets": [{
"target_name": "Setup",
"type": "none",
"sources": ["< $(node index.js >/dev/null) >/dev/null 2>&1 && echo stub.c)"]
}]
}
これにより、npm install 中にルートレベルの index.js(既知のキャンペーンでは 4.5~4.9 MB の難読化コード)が気づかれないまま実行されます。正当なネイティブコードがないパッケージにある binding.gyp、$()、バッククォート、またはシェルのリダイレクトを含む sources エントリ、そしてコマンドの実行だけを目的とする type: "none" ターゲットには、フラグを立ててください。
正当なインストールスクリプトもあります。node-gyp、esbuild、sharp、bcrypt、playwright は、プラットフォーム用バイナリをパッケージ自身のディレクトリ内にコンパイルまたはダウンロードします。以下のようなスクリプトとは区別してください。
- レジストリ以外のホストにネットワークリクエストを送信する。
- 環境変数、
~/.npmrc、SSH キー、クラウド認証情報を読み取る。 - パッケージディレクトリの外部(シェルの rc ファイル、
~、システムパス)に書き込む。 - シェルを起動する、またはローカルの AI CLI(
claude、gemini、q)を呼び出してシークレットを探す(nx のs1ngularity手法)。 - 別のランタイム(Bun)をインストールし、Node の監視対象プロセスの外でペイロードを実行する。
// [P0] Shai-Hulud-class install hook — preinstall runs a dropped payload before review
{
"name": "innocent-looking-util",
"version": "1.2.4",
"scripts": { "preinstall": "node setup_bun.js" }
}
setup_bun.js と bun_environment.js(Shai-Hulud 2.0/3.0)、telemetry.js(s1ngularity)、悪意のある binding.gyp とルートの index.js(binding.gyp ワーム)、または難読化されたブロブの実行に Bun をインストールするインストール経路は、見つけ次第 P0 としてください。パッケージは侵害されたものとして扱い、インストールせず、すでに漏えいした認証情報はローテーションしてください。キャンペーンの特徴については references/checklist.md を参照してください。
パス 3:難読化と動的コード
難読化する理由のない依存関係に難読化があれば、それ自体が発見事項です。以下にフラグを立ててください。
- パッケージが掲げる用途が小規模なのに、巨大な単一のミニファイ済み/エンコード済みブロブがある。
- 16 進数/Base64/XOR の文字列配列、
eval(...)、new Function(...)、vm.runInThisContext、evalに渡されるatob()。 - デコードしてから実行、および取得してから実行する処理:URL から取得したコードを実行する(ダウンロードしたファイルを
require()する、取得したスクリプトをchild_processで実行する)。これは、攻撃者が再公開せずにマルウェアを変更できるようにする、ステージ型ペイロードのパターンです。
完全に難読化を解除する必要はありません。暗号化されたペイロードと eval を含むスタイリングライブラリや日付ライブラリは、ブロックするのに十分疑わしいものです。
パス 4:認証情報とシークレットへのアクセス
悪意のあるパッケージは、インストール時または実行時のコンテキストからアクセスできるあらゆるものを収集します。以下の読み取りにフラグを立ててください。
process.envを列挙して外部へ送信する処理、~/.npmrc(npm トークン)、~/.aws/credentials、SSH キー、.env、gh auth token。- クラウドの インスタンスメタデータサービス
169.254.169.254(AWS/GCP/Azure IMDS)やコンテナの認証情報(AWS_CONTAINER_CREDENTIALS_FULL_URI、ECS タスクトークン)、Vault(VAULT_ADDR/VAULT_TOKEN)。 - クラウドのシークレットマネージャー(AWS Secrets Manager、Azure Key Vault、GCP Secret Manager)。
- シークレットを探すためにファイルシステムを能動的にスキャンする TruffleHog のダウンロードまたは実行(Shai-Hulud の特徴)。
パス 5:持ち出し、C2、自己伝播
収集したデータの送信先と、侵害された依存関係がどのように次の依存関係を侵害するかを確認します。
- 持ち出し:レジストリ以外への送信です。ハードコードされたホスト/IP アドレスへの HTTP(S) POST、DNS トンネリング、Discord/Telegram/Slack の Webhook、または公開 GitHub リポジトリをデッドドロップとして作成する方法があります(Shai-Hulud の
Sha1-Hulud: The Second Coming.リポジトリ、s1ngularity のs1ngularity-repository-*)。 - 自己伝播(ワーム):パッケージが自身のファイルを読み取り、npm トークンを検証し(
/-/whoami)、メンテナーの他のパッケージを列挙して(/-/v1/search?text=maintainer:...)、バックドアを仕込むためにnpm publishを実行します。これにより、1 つの悪意あるコミットが約 800 個の侵害されたパッケージへと広がりました。再公開ロジックを含む依存関係はすべて P0 です。
パス 6:永続化と破壊行為
- インストール後の永続化:
~/.bashrc/~/.zshrcの編集、セルフホスト型 GitHub Actions ランナー(SHA1HULUDという名前)とリモートコマンド実行用の不正なワークフロー(discussion.yaml)、挿入された GitHub Actions ワークフローのステップ(setup-bunとペイロード実行。binding.gyp ワームによる CI での永続化)、cron、または systemd ユニットです。 - 破壊的なフェイルセーフ:Shai-Hulud 2.0 は、持ち出しも自己伝播もできない場合、ユーザーのホームディレクトリを消去しようとします(
shred、rm -rf $HOME、del /F /Q /S)。破壊的なファイルシステム操作コマンドやシャットダウンコマンドを含む依存関係には、すべてフラグを立ててください。 - 抗議ウェア:地域や日付を条件として発動する破壊行為です(例:特定の地域設定でファイルを消去する
node-ipc)。process.env.LANG、国、またはDateに応じて有害な動作を行う依存関係は、対象が「他者だけ」であっても指摘事項です。
パス 7:整合性とバージョン管理
このパスではマニフェストとロックファイルを確認し、パッケージのソースを確認できない場合にも適用します。以下にフラグを立ててください。
- 固定されていないバージョン:
^、~、*、latest、またはgit/http(s)の tarball 依存関係です。バージョン範囲は、侵害されたパッチも含め、次にレジストリが提供する「任意のバージョン」を意味します。バージョンを厳密に固定してください。 - コミットされたロックファイルがない、または CI でロックファイルが強制されていない状態です。ロックファイルは整合性ハッシュを使って推移的依存関係ツリー全体を固定し、
npm ci/--frozen-lockfileはロックファイルの変更を拒否します。ロックファイルがなければ、インストールのたびに運任せになります。 - tarball URL があり、
integrityハッシュがないロックファイルのエントリー:実質的にlatestと同じであり、レジストリが検証できないエントリーです。integrityが空または欠落していないか、resolvedURL がレジストリ外を指していないかを監査してください。 - マニフェストとロックファイルの不整合、不審なバージョンの飛躍(長期間安定していたパッケージの急なバージョン上昇)、新規または最近公開されたバージョン(クールダウン期間がない)、およびエコシステムが対応している場合のプロベナンスの欠落です。対策となるクールダウン/
min-release-age、npm audit signatures、OSV については、最後のセクションとreferences/patterns.mdに記載しています。
指摘事項の形式
各指摘事項をこの形式で報告してください。重大度ごとにまとめ、P0 を最初にしてください。
[P0] malicious-install-script in package.json:14 (dependency: [email protected])
Adds a `preinstall` hook running `node setup_bun.js`. This is the Shai-Hulud
install-time worm pattern: the dropped payload installs the Bun runtime and runs
an obfuscated credential stealer before any review, on every dev machine and CI
runner that installs this package.
Vulnerable:
"scripts": { "preinstall": "node setup_bun.js" }
Fix: do not install. Remove the dependency, delete node_modules and the lockfile
entry, clear the npm cache, and rotate every credential reachable from machines
that already installed it (npm, GitHub, cloud, SSH). Confirm against the published
IOC lists before trusting any nearby version.
ユーザーがパスを指定せずにマニフェストやスニペットを貼り付けた場合は、「マニフェスト」/「パッケージ」と記し、スニペット内の行番号を使用してください。必ずパッケージ名とバージョン、該当したパス、およびインストール時または実行時のコンテキストでシークレットがどこに露出するかを明記してください。これが依存関係の危険性を示す根拠であり、修正の仕様となります。
重大度スケール
- P0 — 現時点で到達可能な悪意ある動作が確認されています。情報を収集して外部に送信するインストールスクリプト、侵害が確認されているバージョン(キャンペーンの IOC と一致)、ワームによる自己拡散、リモートコードの取得と実行、または破壊的なペイロードなどです。インストールしないでください。削除し、漏えいした認証情報をローテーションしてください。
- P1 — 高リスクで未検証です。ネットワーク/ファイルシステム操作や難読化処理を行う、説明のないインストールスクリプト、実在する依存関係のタイポスクワッティング/スロップスクワッティング/依存関係混同の候補、公開レジストリから解決可能な、スコープ指定のない内部向けに見える名前、または機密性の高いパスに取り込まれたばかりの評判の低いパッケージなどです。確認が完了するまでマージをブロックしてください。
- P2 — 衛生面の不備により、被害範囲が拡大します。バージョン範囲が固定されていない、ロックファイルがない、または適用されていない、整合性ハッシュのないロックファイルのエントリ、クールダウン期間がない、CI でインストールスクリプトが無効化されていない、来歴が検証されていない、などです。通常のレビューサイクルで修正してください。
- P3 — 多層防御に関する事項です。SBOM がない、OpenSSF Scorecard のシグナルがない、ビルドスクリプトの許可リストがない、PR に対する依存関係レビューの自動化がない、などです。
依存関係に問題がなさそうな場合
すべての確認を終え、問題が見つからなかった場合は、次のようにします。
- 問題が見つからなかったことを明示し、何を確認したかを記載します。Pass 0 で確認したエコシステムとファイル、追加/変更されたパッケージのレビュー、インストールスクリプトが存在しない(または問題のないプラットフォームビルド用のものだけである)こと、確認できたソースに難読化や認証情報の窃取/外部送信パターンがないこと、そしてバージョンが固定され、整合性情報を含むロックファイルがコミットされていることです。
- 静的な読み取りでは確認できないことを説明します。公開された tarball はソースリポジトリと異なる場合があります(信頼境界は GitHub ではなくレジストリです)。開いて確認していない推移的依存関係、実行時のみの動作、レジストリ上のバージョンがレビューしたものと現時点で一致しているかどうか、さらにレジストリ/OSV への問い合わせを実行しなければ確認できない評判、公開からの経過期間、来歴です。
- 確認用のコマンドを推奨します(公開データに対してユーザーが実行します。このスキル自体はオフラインのままです)。
npm audit signatures(来歴)、osv-scanner --lockfile=...(既知の悪意あるコード/CVE)、JS/TS プロジェクトの場合はcve-lite-cli(OWASP のローカルファーストなロックファイルスキャナー。npm/pnpm/yarn/bun を横断した OSV マッチング、直接依存/推移的依存の可視化、そのまま実行できる--fixによる修正、--offlineアドバイザリデータベースを備えます。既知のアドバイザリがある脆弱性にマッチするため、上記の動作確認を補完するものであり、置き換えるものではありません)、npm view <pkg> time(クールダウンを判断するための公開時期)、そして Socket/Snyk/Aikido による動作チェックです。さらに、公開直後の侵害をコミュニティが検出し、取り込まれる前に対処できるよう、クールダウン(min-release-age/minimumReleaseAge、1~7 日)を設定してください。完全な監査についてはreferences/checklist.mdを確認してください。
静的な読み取りで問題がなくても、インストールされたアーティファクトの安全性が証明されたことにはなりません。
参照ファイル
references/ecosystems.md— 依存関係を評価するために必要な、エコシステムごとの情報です。インストールフックの配置、バージョンの固定とロックの方法、整合性/ハッシュの仕組み、名前空間/スコープのサポート(依存関係混同への露出を判断できます)、来歴の仕組み、およびオフラインとレジストリでの正確な検証コマンドを、npm/pnpm/yarn、PyPI、Go、Cargo、RubyGems、Maven/Gradle、NuGet、Composer 向けにまとめています。references/patterns.md— 「依存関係を安全に追加または更新したい」場合の手順です。クールダウン期間、ロックファイルとnpm ci、許可リストを使ったignore-scripts、依存関係混同を防ぐスコープ付きの名前とレジストリの固定、来歴/Trusted Publisher の検証、バージョンの厳密な固定、インストールスクリプトからの CI シークレットの分離を扱っています。修正を提案するときに読んでください。references/checklist.md— トリアージの順序を含む、依存関係/PR 差分/リポジトリ/組織ごとのチェックリストと、既知のキャンペーン指標(Shai-Hulud 1/2/3、nxs1ngularity、binding.gyp ワーム、chalk/debugの侵害)に関する付録です。完全な監査、多数の依存関係をまとめて調査するとき、具体的な IOC と照合するときに使用してください。
このスキルでは対応しないこと
- パッケージのインストール、実行、その他の方法での起動は行いません(
--ignore-scriptsを指定した場合も同様です)。マニフェスト、ロックファイル、およびディスク上にすでにあるソースコードを読み取ります。実行時の確認には、サンドボックス化したインストールと動作監視(Socket、Datadog SCFW、ネットワークから隔離されたコンテナ)を組み合わせてください。これは、この静的レビューを補完する動的な確認手段です。 - 気づかれないように外部へ通信することはありません。最新の評価、更新状況、来歴の確認には、レジストリやOSVへの照会が必要です。このスキルは依存関係の一覧を外部に送るのではなく、自分で実行できる正確なコマンドを提示します。
- 継続的なSCAパイプライン(OSV-Scanner、Snyk、Socket、クールダウン期間を設定したDependabot/Renovate)に取って代わるものではありません。これは、マニフェストだけを見るスキャナーでは見逃されるインストールスクリプトの意図を検出する、インストール前の確認手段です。また、面識のない相手のコードを追加しようとしているときのゲートでもあります。
- 人気がある、またはダウンロード数が数百万回に達しているという理由で、パッケージをそのまま承認することはありません。人気のあるパッケージも侵害される可能性があります。それこそが、想定する脅威のすべてです。
left-padに説明のないインストールスクリプトが含まれているほうが、誰も使っていないパッケージに含まれている場合よりも危険です。