Skip to main content

Node.jsに実験的な整合性ポリシーを導入

著者

2019年3月21日

0 分で読めます

整合性ポリシーを導入する実験的な機能が、Node.js 11.8.0のコアに最近追加されました。まだLTS版には搭載されていないこの機能は、モジュールの読み込み時にNode.jsランタイムの整合性を検証し、モジュールのコードが改ざんされていないことを確認します。

Bradley Fariasは2018年10月にこの変更を提案しました。ブラウザーにある同様のセキュリティ機能、Subresource Integrityから着想を得ています。

Subresource Integrity

World Wide Web Consortium(W3C)は、HTML文書内のサブリソースを検証できるようにする新しいintegrityフィールドをHTML仕様に提案しました。Webページでは、scriptタグやlinkタグを使ってブラウザーにリソースを読み込ませることができます。しかし、こうしたHTML要素でintegrityフィールドを使用しない限り、リソースが改ざんされていないかを検証する方法はありません。

Webページは、自サイトまたはサードパーティーのリソースをリモートサーバーから読み込みます。その際、最も一般的に使われるのがコンテンツデリバリーネットワーク(CDN)です。こうしたリソースを読み込むとき、リソースファイルの整合性を検証することで、悪意ある攻撃者から保護できます。たとえば、次のようなケースが考えられます。

  • 侵害されたリモートサーバーが、変更されたリソースファイルを配信する

  • 転送経路が侵害され、リソースファイルが改ざんされる

Node.jsモジュールの整合性ポリシー

ブラウザーのセキュリティ機構によるリソース整合性の強制に着想を得て、Node.jsでも同じように、プログラムコードがサードパーティーモジュールを要求した際に、メモリーに読み込んで実行する前に整合性を検証できるとしたらどうでしょうか。

Node.js 11.8.0の新しい実験的なポリシー機能では、コマンドラインフラグ--experimental-policyを使ってこの動作を強制できます。このフラグには、プロジェクト内のすべてのリソースを記述したポリシーマニフェストを指定します。仕組みを見てみましょう。

Node.jsのポリシーマニフェスト

11.8.0ではモジュールローダーによる強制機能のみが提供されていますが、Node.jsは現時点でポリシーマニフェストを処理できません。ポリシーファイルの管理には、Bradleyが開発したnode-policy CLIヘルパーを使えます。

npm install -g @bradleymeck/node-policy

node-policyのintegrity:addコマンドを実行すると、現在のディレクトリにあるすべてのファイルの暗号学的ハッシュを含むポリシーマニフェストを作成できます。.git/ディレクトリからnode_modules/の全コンテンツまで、すべてが対象となるため、生成には少し時間がかかります。

この仕組みを説明するために、typeformのアンケート結果をエクスポートするために作成したCLI用Node.jsモジュールで試してみます。

node-policyを実行し、現在のディレクトリ内にあるすべてのファイル(最後のドットで指定)を対象とする整合性マニフェストを作成します。また、暗号学的ハッシュ関数に使うアルゴリズムを指定します。選択できるのはsha256、sha384、sha512で、いずれもSubresource IntegrityのHTML仕様に対応しています。

node-policyの整合性コマンドと、37,945個の整合性値が.node-policy.jsonファイルに追加されたことを示すターミナル。

生成されたプロジェクトのポリシーファイルは、ユーザーのホームディレクトリに保存されます。.node-policy.jsonの一部を以下に示します。ファイルのURLと整合性ハッシュを含むマニフェストの構造を確認できます。

"resources": {
    "./projects/repos/typeform-export-excel/.git/COMMIT_EDITMSG": {
      "integrity": "sha256-dMEh66Uy32Nr8wO5fy3FAEsZjTeqpBghe9o48gYgZfM="
    },
    "./projects/repos/typeform-export-excel/.git/FETCH_HEAD": {
      "integrity": "sha256-NsU93Hbe+fB2KxZIzQnA299sQRl/4Fg1wk9M0FSYe7E="
    },
    "./projects/repos/typeform-export-excel/node_modules/zip-stream/index.js": {
      "integrity": "sha256-JUKnwX/rS+DRZ0tEQjTl4B/qb3/z7DRMqYiPy9EJpOg="
    },
    "./projects/repos/typeform-export-excel/package.json": {
      "integrity": "sha256-8YN17NVVfPPW+CWsQ2j5LF9MbcnTu6ny/MFkVj/pXjI="
    },
    "./projects/repos/typeform-export-excel/src/constants.js": {
      "integrity": "sha256-wGKtyPIeYuAc0D5L7SrPeiXOqvZYNgqJLkxi8aA/OiQ="
    },
    "./projects/repos/typeform-export-excel/src/index.js": {
      "integrity": "sha256-eJnVeGBKu6vVMHPVS2PKpK6/adC6YLiAEyoIqQwwOjI="
    }

別のプロジェクトディレクトリでnode-policy CLIを実行すると、このポリシーマニフェストにファイルが追加されます。これはnode-policy独自の実装であり、仕様やガイドラインではありません。

node-policyがポリシーファイルをユーザーのホームディレクトリに作成するのはなぜでしょうか。整合性ポリシーに関する包括的なベストプラクティスはまだ標準化されていませんが、このファイルは信頼できるリソースの基準となるため、何らかの方法で改ざんされないよう保護するのが最善です。ファイルを読み取り専用に設定し、アクセスされる可能性のあるディレクトリの外に配置することをおすすめします。

ファイルの改ざんとNode.jsによる検出の仕組みを再現するため、CLIプロジェクトに含まれるbin/cli.jsのコードを少し変更しました。実行可能なCLIのJavaScriptコードをNode.jsで実行すると、CommonJSモジュールを読み込む前にハッシュが異なることを検出し、エラーを出してNode.jsをコマンドプロンプトに戻します。

bin/cli.jsでERR_MANIFEST_ASSERT_INTEGRITYエラーが発生し、Node.jsのコマンドが失敗しているターミナル。

現在の実装では、エラーをスローしたりプログラムを終了したりする代わりに、整合性の不一致をログに記録できます。これは、ポリシーマニフェストファイルのトップレベルオブジェクトにonerrorプロパティを追加することで実現できます。

まとめ

Node.jsへのセキュリティ機能の組み込みは着実に進んでおり、近い将来さらに多くの機能が登場するでしょう。整合性ポリシー機能はまだ実験段階であり、Node.js 11.8.0以降でのみ利用できる点にご注意ください。

CTFを始めよう

オンデマンドのバーチャル入門ワークショップを視聴して、CTFの課題の解き方を学びましょう。

続きを読む

blog feature ai violet
Blog

VulnBump:AIエージェントはビルドを壊さずに脆弱な依存関係を修正できるか?

VulnBumpは、実際の依存関係アップグレード307件を対象にAIエージェントをテストします。脆弱性が解消され、ビルドとテストが成功した場合にのみ、修正としてカウントされます。

blog feature snyk container custom base recommendations
Blog

Evo Agentic AppSecのご紹介:AI開発のスピードに対応するセキュリティ

AI駆動型開発のスピードに、従来のセキュリティワークフローは追いついていません。SnykのAgentic AppSecは、セキュリティエージェントが脆弱性を継続的に検出、修正、検証し、人が基準を定められるようにします。

Blog

フロンティアモデルは脆弱性を発見した。攻撃者だけがエクスプロイトチェーンを見つけた。

静的解析で欠陥は見つかりましたが、ライブ攻撃テストで侵害につながる連鎖を実証できたのは唯一でした。Evo COS、Claude Security、Claude Code Securityを比較します。