2026 年 5 月、Publickey が 「npm install」は任意コード実行のようなもの? Trivyやaxiosへのサプライチェーン攻撃を踏まえた、開発環境への新たな向き合い方 を公開し、再び「npm install を漫然と打つ時代は終わった」という警鐘が広く共有されました。Trivy 配布パッケージへの侵入と axios npm への悪意あるバージョン公開が同時期に起きたことで、「OSS をどう使うか」よりも「OSS をどう取り込むか」にセキュリティ投資の重心が移りつつあります。
弊社では受託開発で構築する全プロジェクトで、**「npm install を実行する環境を本番から完全に隔離する」**ことを標準にしています。本記事では、開発者端末・CI・本番ビルドの 3 層を分離する DevSecOps 設計と、運用ルールを整理します。
「npm install は任意コード実行」とはどういう意味か
npm install の処理は、依存パッケージのスクリプトフィールドを通じて任意のシェルコマンドを実行する余地を持ちます。これは仕様であり、悪用されると一瞬で開発者端末が乗っ取られます。
| トリガー | 実行されるもの | リスク |
|---|---|---|
preinstall / postinstall | npm パッケージに同梱されたスクリプト | クレデンシャル収集、外部送信 |
prepare / prepublishOnly | パッケージ公開前後の処理 | ビルド成果物の差し替え |
| ネイティブモジュールビルド | C/C++ コードのコンパイル | 実行ファイルへの混入 |
| バイナリの post-download | OSS が独自に DL するバイナリ | 偽バイナリの実行 |
特に問題なのは、「数百〜数千の依存ツリー全体に対してこれが起きうる」点です。直接依存するのは 30 個でも、推移的依存を含めれば 2000 個を超えるパッケージに対して、自分のマシン上で任意のコードが走る権利を与えていることになります。
これは 2026年サプライチェーン攻撃まとめ で扱った Axios・LiteLLM 事件の “なぜ防げなかったか” を、インストール時点の権限設計から見直す動機になります。
受託で標準化すべき 3 層分離アーキテクチャ
弊社が受託案件で標準化している環境分離は次の 3 層です。
[Layer 1: 開発者端末(Mac/Windows)]
├ 直接の npm install は禁止
├ Devcontainer / GitHub Codespaces 内でのみ実行
└ シークレット・本番アクセス権を持たない
[Layer 2: CI / Build 環境(GitHub Actions / Cloud Build)]
├ 1 ジョブ 1 コンテナで使い捨て
├ ネットワークは npm registry / proxy のみ許可
├ シークレットは最小権限の OIDC 経由
└ ビルド成果物は署名 + ハッシュ記録
[Layer 3: 本番ランタイム(GCP / AWS / Cloudflare)]
├ npm install は実行しない
├ ビルド成果物のみをデプロイ
└ Outbound 通信は許可リストのみ
ポイントは 「Layer 1 と Layer 3 が同じシークレットを持たない」 設計です。開発者端末がどれだけ汚染されても、本番には届かない構造を物理で担保します。これは マネーフォワード GitHub 事件から学ぶ受託シークレット監査 で扱った “シークレットを Git に置かない” 設計と表裏一体で考えるべきテーマです。
Layer 1 の具体策 — 開発者端末を “汚れていい場所” にする
開発者端末上で npm install が走る場合、「いつでも捨てられる隔離環境」で動かすことが必須です。弊社で採用しているパターンは以下の 3 通り。
| パターン | 構成 | 利点 | 注意点 |
|---|---|---|---|
| Devcontainer (VS Code) | ローカル Docker | 動作軽快、オフライン可 | Docker 設定の標準化が必要 |
| GitHub Codespaces | クラウドコンテナ | 端末が貧弱でも動く、廃棄が容易 | 月額コスト、ネット必須 |
| Cloud Workstations (GCP) | GCP 上の VM | 大規模リポにも耐える | 初期費用と運用負荷 |
中小〜中堅の受託では Devcontainer + Codespaces ハイブリッドが現実的なバランスです。新規セットアップ時には Codespaces で素早く立ち上げ、安定運用に入ったら Devcontainer に降ろす、という二段構えで運用します。
Layer 2 の具体策 — CI のネットワーク制御と署名
CI 上で npm install を流すとき、外部レジストリへの接続を絞ることが最大の防御です。
- Verdaccio や JFrog Artifactory を社内プロキシとして立て、社内承認パッケージのみ通す
- ネットワークアロウリストで
registry.npmjs.org以外は遮断 npm ci --ignore-scriptsをデフォルトにし、scripts 実行は明示的に許可した場合のみnpm install後にnpm audit signaturesを必ず実行し、署名検証- SBOM(Software Bill of Materials)を CycloneDX 形式で生成し、リポジトリに保管
特に --ignore-scripts のデフォルト化は実装コストの割に効果が大きい施策で、postinstall 経由の侵入を一括でブロックできます。スクリプトが必要なパッケージは案件ごとに個別許可リストで管理します。
Layer 3 の具体策 — 本番では絶対に install しない
本番ランタイムでは npm install を一切実行しないのが鉄則です。Cloud Run / Lambda / Cloudflare Workers などのサーバーレス基盤は、CI で生成した artifact を直接配置します。これにより:
- 本番イメージのサイズが半分以下になる(dev dependencies が消える)
- 起動時間が短縮される(依存解決がない)
- 新しい脆弱性パッケージが本番に紛れない(イミュータブル)
イミュータブルな成果物を CI が署名し、本番は Sigstore / Cosign で検証してからデプロイする構成が、現在の受託のベストプラクティスです。これは GitHub eBPF 活用に学ぶデプロイ安全性 で扱った “デプロイ時の侵入検知” と一体で組み立てるべきテーマです。
価格モデル — DevSecOps を組み込んだ受託パッケージ
サプライチェーン攻撃対策を含めた受託パッケージは、以下の価格レンジで提供しています。
| プラン | 初期 / 月額 | 対象 | 内容 |
|---|---|---|---|
| DevSecOps Lite | 50 万円 / 5 万円〜 | 既存案件への後付け | Devcontainer 整備 + npm audit CI 化 |
| DevSecOps Standard | 150 万円 / 20 万円〜 | 新規受託・継続案件 | Lite + Verdaccio + SBOM + 署名検証 |
| DevSecOps Enterprise | 400 万円〜 / 60 万円〜 | 上場・コンプラ要件あり | Standard + 監査ログ Streaming + 月次レポート |
中小企業にとって、月額 5〜20 万円で「サプライチェーン攻撃の侵入経路」が物理的に断たれるのは費用対効果が極めて高い投資領域です。年 1 回の高額外注と違い、毎日防御が効く点で経営層への説明もしやすいパッケージです。
ハマりやすい 5 つの落とし穴
最後に、受託で DevSecOps を組み立てるときの落とし穴を共有します。
落とし穴 1: 「開発者の利便性」を盾に Layer 1 を壊す
「ローカル直接 install できないと開発が遅くなる」という声で Devcontainer 運用が形骸化するケースが多発します。新規参画時のオンボーディング 1 日で Devcontainer の操作を体に入れてもらう運用が必要です。
落とし穴 2: SBOM を作るだけで使わない
CycloneDX を生成しても、新しい脆弱性が出たときに過去の SBOM を検索する仕組みがないと意味がありません。Dependency-Track 等で 集中管理 + 自動アラートまで組みます。
落とし穴 3: 社内プロキシのキャッシュ汚染
Verdaccio や Artifactory のキャッシュに過去に侵害されたバージョンが残ったまま運用されるケースがあります。月次でキャッシュを再生成する運用を組みます。
落とし穴 4: ロックファイルを更新しない
package-lock.json を更新せず半年放置すると、既知脆弱性のまま固定されます。月次の Renovate / Dependabot 棚卸しを組み込みます。
落とし穴 5: 顧客の独自パッケージへの目配り
顧客が自社で公開している private npm パッケージは、顧客側の侵害が直接弊社の CI に入ってくる経路になります。双方向の SBOM 交換を契約に組み込みます。
まとめ — npm install を “祈り” から “設計” に変える
npm install を実行することは、「2000 個の他人のコードに自分の端末を貸す」行為です。受託で扱う以上、この事実から目を逸らすことはできません。Devcontainer / 社内プロキシ / SBOM / 署名検証の 4 点セットを 「やるかやらないか」ではなく「どこまで深くやるか」の議論に持ち込めるかが、これからの受託品質を分けます。
弊社では DevSecOps Lite / Standard / Enterprise の 3 段階で受託パッケージを提供しています。「過去に開発した案件のサプライチェーン耐性が不安」「新規案件で最初から DevSecOps を組み込みたい」というご相談は お問い合わせフォーム からお気軽にどうぞ。