ていぎ
npm (node package manager) は、JavaScriptおよびTypeScriptの一般的なプログラミング言語向けのデフォルトのパッケージマネージャーです。公開およびプライベートのコードパッケージ向けの世界最大のオンラインソフトウェアレジストリの1つとして機能し、開発者がそのレジストリと対話してプロジェクトの依存関係の検出、インストール、管理、更新、公開のプロセスを自動化するために使用するコマンドラインインターフェース(CLI)クライアントを提供します。
npmの概要
npmは基本的に、大規模なオンラインレジストリと、クライアント側のコマンドラインツール2つの部分から成るシステムです。再利用可能なコードモジュールの管理プロセスを自動化し、オープンソースのコラボレーションとエンタープライズ規模の開発の両方に不可欠です。
npmの主な機能の中心は、パッケージのライフサイクルの自動化にあります。
npm installコマンドは依存関係を解決してパッケージをダウンロードするのに対し、npm publishは新規または更新されたパッケージをレジストリにアップロードします。このツールは、依存関係の互換性を確保するためにバージョン管理を行い、プロジェクトのpackage.jsonファイル内のパッケージ情報を追跡します。
npmレジストリとCLIを使い始める方法
パブリックnpmレジストリは、JavaScriptおよびtypescriptのエコシステムの主要な配布ハブとして機能し、npm CLIは、開発者がそれらのパッケージにアクセスして管理するための直接のゲートウェイです。
最も一般的なパブリックnpmレジストリは https://www.npmjs.com/ です。
Node.jsとCLIクライアント
npmはNode.js(JavaScriptランタイムエンジン)にバンドルされているため、Node.jsをインストールすると、npm CLIクライアントが自動的にインストールされます。インストールすると、開発者はレジストリのパッケージを管理し、アクセスできます。初期設定および構成の詳細については、npmのスタートガイドをご覧ください。
インストールと構成
インストールプロセスでは通常、npm CLIを含む対象オペレーティングシステム向けのNode.jsインストーラーをダウンロードして実行します。インストール後、CLIはコマンドラインから直接使用できます。デフォルトでは、CLIはnpmjsのパブリックのリポジトリからパッケージをダウンロードします。プライベートレジストリまたはセルフホスト型レジストリを設定するには、.npmrcを使用してnpm CLIがJFrog Artifactoryに接続する場合と同様に、CLIが正しいレジストリURLを参照して認証を処理できるように、設定ファイル.npmrcを更新する必要があります。
package.jsonの作成と管理
package.jsonは、すべてのNode.jsプロジェクトのマニフェストファイルです。プロジェクト名、バージョン、説明、メインエントリポイント、そして極めて重要なすべての必須依存関係など、メタデータを一元的に定義します。このファイルを管理することは、プロジェクトの移植性を確保し、複数の環境にわたって確実に再現できるようにするために重要です。
依存関係管理の基礎
効果的な依存関係管理は、拡張性に優れたJavaScript開発の基盤です。npmでは、プロジェクトが外部コードモジュールを追跡および利用する方法をきめ細かく制御できます。
依存関係の種類
package.jsonファイルでは、プロジェクトのライフサイクルにおける役割に基づいて依存関係を分類します:
dependencies:本番環境でアプリケーションを実行するために必要なパッケージ。devDependencies:テストランナーやリンターなど、ローカルでの開発、テスト、ビルドにのみ必要なパッケージ。peerDependencies:アプリケーションが、利用者が既に持っていることを前提とする依存関係。これはプラグインやアドオンによく見られるものです。optionalDependencies:アプリケーションが存在すれば使用しようとする依存関係ですが、存在しなくてもインストールは失敗しません。
セマンティックバージョニング(SemVer)
セマンティックバージョニング(SemVer)は、3つの部分からなるバージョン文字列(MAJOR.MINOR.PATCH)であり、導入される変更内容に基づいてバージョンの増分方法を規定します。MAJORバージョンの変更は互換性のないAPIの変更を示し、MINORは後方互換性のある新機能を示し、PATCHは後方互換性のあるバグ修正を示します。npmは、^1.0.4や~1.0.4などのプレフィックスをpackage.jsonで使用し、SemVerルールに基づいて許容可能なバージョン範囲を定義します。
上書きと競合の解決
依存関係の競合は、パッケージによって互換性のないSemVerの範囲が導入されると一般的に発生し、複雑または不安定な依存関係ツリーにつながります。package.jsonのnpmのoverridesフィールドは、グラフ内の任意の依存関係に対してパッケージマネージャーに特定のバージョンを明示的に使用させることで、問題を引き起こす可能性のあるサブ依存関係を上書きします。これにより、深くネストされた依存関係における競合を解決し、セキュリティ脆弱性を軽減するためのきめ細かな制御が可能になります。
最後に正常にインストールされた際に使用された正確な依存関係ツリーを記録することで決定論的なビルドを確保するために、package-lock.jsonファイルは非常に重要です。このファイルには、package.jsonで指定されたセマンティックバージョニングの範囲に関係なく、推移的依存関係を含むすべてのパッケージのバージョン、ソース、Subresource Integrity(SRI)ハッシュの詳細が記載されています。後続のユーザーまたはCI/CDプロセスがnpm installを実行すると、package-lock.jsonが存在することで、これらの正確なバージョンのインストールが強制されます。これにより、パッケージのバージョン解決が実質的にバイパスされ、大規模なプロジェクトの依存関係グラフ全体で競合するバージョン要件によってしばしば発生する依存関係の問題が軽減されます。
npmパッケージをビルドして公開する方法
JavaScriptパッケージは通常、package.json ファイルを含むディレクトリです。このパッケージを他のユーザーが利用できるようにするプロセスには、慎重な準備とレジストリへの公開が伴います。
パッケージ配布の準備
事前準備を行うことで、パッケージが利用に適した構成になっていることを確認できます。これには、主要なエントリポイント、想定されるランタイム環境、および必要なすべてのメタデータを定義することが含まれます。十分に整備されたパッケージは、その目的、依存関係、制約を他の開発者に明確に伝えます。
必須ファイルのセットアップ
配布に必要なファイルには、README.md(使用方法と目的を記載)、LICENSE(再利用に関する法的条件を定義)、CHANGELOG(バージョン履歴と主な変更点を詳述)が含まれます。SemVerバージョンや作成者情報などの重要なメタデータは、package.jsonで定義されます。
パッケージのバージョン管理とリリース
パッケージのバージョン管理は、SemVerのルールに準拠する必要があります。npmでは、npm version コマンドによってバージョン管理が簡素化されます。このコマンドは、package.json 内のバージョン番号を自動的に更新し、対応するGitタグを作成します。リリースは、バージョンがタグ付けされ、コミットされた後にnpm publishを実行することによって正式に実行されます。
npmにおけるセキュリティ上の主な課題は?
node package manager (npm) はJavaScript開発の中心的な存在であるため、アプリケーションセキュリティ(AppSec)の侵害の主要な標的となっており、高度なサプライチェーン攻撃につながっています。セキュリティ上の主要な課題は、レジストリの膨大な規模と、開発者がパッケージに対して抱く本来的な信頼に起因しています。
ソフトウェアサプライチェーンにおけるJavaScript依存関係の保護は、重要なAppSecの課題です。主な攻撃手法は、パッケージ利用モデルにおける脆弱性や悪意のあるコードの注入を悪用するものです。
npmのセキュリティに関する主な課題は以下のとおりです。
1. アカウント乗っ取りとパッケージポイズニング攻撃
攻撃者は、信頼されているパッケージメンテナーのアカウントを侵害し(多くの場合、基本的な2FAを回避する高度なフィッシングを介して)、その公開パッケージを乗っ取り、人気があり広く使用されているライブラリに悪意のあるコードを注入します。ソフトウェアのソースに対するこの直接的な攻撃は、下流のユーザーを即座に侵害する深刻なサプライチェーン攻撃です。
2025年9月の最近の事例では、メンテナーのアカウントを侵害して、debugやchalkなどのライブラリにマルウェアを混入させることで、npm史上最大の攻撃が発生しました。その直後、「Shai-Hulud」ワーム攻撃は自己増殖によってさらに500件を超えるパッケージを侵害し、npmやクラウドのトークンなどの認証情報を窃取したうえで、侵害したアカウントを使って悪意のあるバージョンを公開し、自動的かつ継続的に拡散しました。
これらのインシデントは、侵害された開発者の認証情報や自動化された悪意のあるペイロードがもたらす極めて深刻な脅威を浮き彫りにしており、ソフトウェアサプライチェーンのあらゆる段階における厳格なスキャンとセキュリティゲートの必要性を強調しています。
2. 依存関係の肥大化と推移的リスク
現代の一般的なアプリケーションは、数百、あるいは数千もの推移的依存関係(明示的にインストールしたパッケージによってインストールされるパッケージ)に依存しています。この隠れたチェーンの奥深くにある単一の依存関係に含まれる脆弱性や悪意のあるコードが、ビルドプロセス中に自動的に実行され、巨大で不透明な攻撃対象領域が作り出されます。開発者は、この深い依存関係グラフを可視化できないことが多く、そのため手動でのリスク評価は事実上不可能になります。
3. 悪意のある実行スクリプトとインストール後のフック
npmパッケージには、インストールプロセス中に自動的に実行されるスクリプトが含まれている場合があります。具体的には、postinstallのようなライフサイクルフックを介して実行されます。攻撃者はこの正規の機能を悪用し、開発者がnpm installを実行した直後に、任意のコード(環境変数の収集、認証情報の窃取、マルウェアの展開など)を実行します。これにより、攻撃者は開発者のローカルマシン上で実行権限を得ることができ、横方向への移動が容易になる可能性があります。
4. タイポスクワッティングと依存関係の混乱
タイポスクワッティングとは、攻撃者が人気のあるライブラリに非常によく似た名前のパッケージを公開する手法です(例:react-dommの代わりにreact-dom)。依存関係の混乱は、プライベートパッケージと同じ名前のパブリックパッケージを登録することで、組織のパッケージ管理の弱点を悪用します。開発者または自動ビルドシステムは、依存関係を解決しようとする際に、誤って悪意のあるパブリックバージョンをプルしてしまう可能性があり、その結果、深刻なセキュリティ侵害を引き起こします。
npm使用時のベストプラクティスとは?
堅牢なベストプラクティスを導入することで、セキュリティリスクを最小限に抑え、コラボレーションを改善し、ソフトウェア開発ライフサイクル(SDLC)全体にわたってNode.jsアプリケーションの信頼性を向上させることができます。
依存関係を効果的に管理
依存関係の管理は受動的なものではなく、能動的なツールを必要とします。チームはロックファイル(package-lock.json)を使用して、決定論的ビルドを確保し、推移的依存関係によって生じる攻撃対象領域を縮小する必要があります。自動化されたソフトウェア構成分析(SCA)スキャンは、パッケージがアプリケーションに統合される前に既知の脆弱性とライセンスコンプライアンスの問題を検出するために、プロセスの早い段階で統合する必要があります。
自動化のためのnpmスクリプトの使用
scriptsフィールドは、package.jsonにおいて、プロジェクト全体のビルド、テスト、開発タスクを標準化するための主要なメカニズムとして活用する必要があります。この一貫性はDevOpsの中核となる原理です。コマンドを標準化することで、開発者は、ローカルマシンから継続的インテグレーションサーバーまで、すべての環境で共通のタスクが予測可能な形で一貫して実行されるようにします。
パッケージを最新かつ安全に保つ
パッケージを定期的に更新することは、セキュリティの観点から重要です。新しいバージョンには、既知の脆弱性に対する修正が含まれていることが多いためです。ただし、破壊的な変更を防ぐために、更新を制御する必要があります。チームは、安全なSemVerの範囲内でアップデートを自動化し、新たにインストールされた依存関係によって重大度の高い脆弱性が持ち込まれないように、自動化されたセキュリティゲートをパイプラインに統合する必要があります。
JFrogはnpmとどのように統合されますか?
JFrog Platformは、開発パイプライン全体を通じてnpmパッケージの使用と配布をセキュリティで保護し最適化する堅牢な一元管理ソリューションを提供します。JavaScriptエコシステムにエンタープライズグレードの制御を拡張し、npmリポジトリとの統合を幅広くサポートします。
JFrog Platformは、JFrog Artifactoryを中核とし、ユニバーサルソフトウェアアーティファクトリポジトリとして機能します。npmパッケージを含むすべてのバイナリアーティファクトの信頼できる唯一の情報源を提供します。この中央ハブはDevOpsの実践に不可欠であり、シームレスな自動化を可能にし、CI/CDプロセスの効率とスピードを向上させます。
JFrog キュレーションは、npmの膨大なパブリックレジストリに内在するセキュリティ上の課題に直接対処します。サードパーティ製のオープンソースパッケージが開発者のワークステーションにダウンロードされたりビルドに統合されたりする前に、セキュリティの脆弱性、マルウェア、ライセンスコンプライアンスの問題がないか自動的に事前にスキャンします。コンテキストを考慮したセキュリティモデルを活用することで、JFrogは悪意のある、またはコンプライアンスに準拠していないパッケージが環境に侵入するのをフィルタリングしてブロックし、パッケージポイズニング、タイポスクワッティング、推移的依存関係の悪用といったリスクの軽減に役立ちます。この好例が、npmの「Manifest Confusion」攻撃です。この攻撃では、JFrog Artifactoryはマニフェストのメタデータファイルに基づくのではなく、実際のpackage.json情報に従って各パッケージをインデックス化して保存することで、ローカルレポジトリを保護しました。
Artifactoryの高度なアーティファクト管理とJFrogのセキュリティ機能を統合することで、組織は不安定なパブリックnpmエコシステムを、信頼性が高くコンプライアンスに準拠したソフトウェアサプライチェーンへと変革できます。
JFrogプラットフォームを使用すると、開発環境に取り込まれるOSSパッケージの管理と保護によりプロアクティブなアプローチを取り、最新のnpm攻撃からJavaScriptのサプライチェーンを保護できます。実際にご確認いただくには、ご都合のよいときにJFrog Curationのオンラインツアーに参加するか、デモを予約するか、無料トライアルを開始してください。
