[緊急解説] HandlebarsにおけるJavaScript Injection(RCE)の脆弱性:フロントエンド開発者が知るべきこと
はじめに:Handlebars利用者の皆様へ
ウェブアプリケーション開発に欠かせないテンプレートエンジンの一つ、Handlebarsに深刻度の高い脆弱性「GHSA-p8wg-vrv2-v86f (CVE-2026-106445)」が報告されました。この脆弱性は、テンプレートからJavaScriptコードを注入し、結果としてリモートコード実行(RCE)を引き起こす可能性があります。特に、ユーザーが制御できるテンプレートを処理するシステムや、特定のオプションを設定している環境で危険性が高まります。日本のフロントエンドエンジニアの皆様も、この情報を理解し、適切な対策を講じることが重要です。
脆弱性の概要と深刻度
今回報告された脆弱性 (ID: GHSA-p8wg-vrv2-v86f / CVE: CVE-2026-106445) は、Handlebarsのプロトタイプアクセスに関する制御の不備に起因します。深刻度は「Critical」と評価されており、悪用された場合の影響は甚大です。具体的には、テンプレートのレンダリング時にJavaScriptの`Function`コンストラクタへのアクセスを許してしまうことで、攻撃者が任意のJavaScriptコードを実行できてしまうというものです。
技術的な詳細:プロトタイプチェーンと`constructor`の悪用
この脆弱性の核心は、Handlebarsの内部でプロパティをルックアップする`lookupProperty`関数の動作にあります。通常、Handlebarsは危険なメソッド(例: `constructor`)へのアクセスを拒否リスト(deny list)でブロックしようとします。しかし、今回の脆弱性はこの機構を巧妙に回避します。
Handlebarsの`lookupProperty`は、まずオブジェクトの「自身のプロパティ(own property)」であるかを`Object.prototype.hasOwnProperty.call(parent, propertyName)`で確認します。もし自身のプロパティであれば、その値を拒否リストのチェックなしに返してしまいます。
ここで問題となるのが、`Function.prototype`のようなプロトタイプオブジェクトの`constructor`プロパティです。例えば、`Function.prototype.constructor`は、`Function.prototype`自身の「独自のプロパティ」として`Function`オブジェクトを指します。このため、テンプレートから`Function.prototype`に到達し、続けて`constructor`プロパティをルックアップしようとすると、Handlebarsはこれを自身のプロパティと判断し、拒否リストによるチェックをスキップして`Function`コンストラクタを返してしまうのです。
結果として、攻撃者はテンプレート内で`Function`コンストラクタを取得し、これを利用して任意のJavaScriptコード(例えば、サーバー上のファイルシステムにアクセスしたり、シェルコマンドを実行したりするコード)を生成・実行することが可能になります。
攻撃シナリオ:RCEへの道筋
この脆弱性を悪用するには、以下の2つの主要な条件が満たされる必要があります。
1. **`allowProtoMethodsByDefault: true` の設定**: Handlebarsのコンパイルオプションで、デフォルトでプロトタイプメソッドへのアクセスを許可している必要があります。このオプションが`false`(デフォルト)の場合、攻撃の可能性は大幅に低減されます。
2. **攻撃者が制御できるテンプレートのレンダリング**: ユーザーからの入力を直接、または間接的にテンプレートとしてHandlebarsに渡すようなシステムが対象となります。
攻撃者は、まずテンプレート内で何らかの関数にアクセスし、その`__proto__`プロパティを通じて`Function.prototype`に到達します。次に、`Function.prototype`の`constructor`プロパティをルックアップすることで`Function`コンストラクタを不正に取得します。一度`Function`コンストラクタを手に入れれば、あとは任意のコードを文字列として渡し、`new Function('return ...')()` のように実行するだけで、サーバーサイドでのリモートコード実行が達成されてしまいます。
提供されたPoCでは、`child_process`モジュールを使ってサーバーの`id`コマンドを実行する例が示されており、深刻な影響があることがわかります。
対策と推奨事項
この脆弱性に対する最も直接的な対策は、以下の通りです。
### 1. `allowProtoMethodsByDefault: true` の使用を避ける
これは、信頼できないテンプレートやデータを扱う際に絶対に行ってはならない設定です。デフォルト値である`false`のまま運用するか、厳密な検証とサニタイズを行った信頼できるテンプレートのみに限定して使用してください。サーバーサイドのNode.js環境でHandlebarsを使用している場合、この設定はRCEに直結するため、特に注意が必要です。
### 2. 信頼できないソースからのテンプレートやデータを扱わない
ユーザーが直接テンプレートの内容を編集・アップロードできるようなシステムでは、セキュリティレビューを徹底し、可能であればHandlebars以外の、より安全なサニタイズ機構を持つテンプレートエンジンを検討してください。
### 3. Handlebarsのアップデート
今後のHandlebarsのセキュリティアップデートで、この問題が恒久的に修正される可能性があります。公式アナウンスを常にチェックし、修正バージョンがリリースされ次第、速やかにアップデートを適用してください。脆弱性の性質上、現在具体的な修正バージョンは発表されていませんが、監視を怠らないようにしましょう。
まとめ
HandlebarsのJavaScript Injection脆弱性は、`hasOwnProperty`チェックとプロトタイプチェーンの相互作用による、見過ごされがちな危険性を示しています。特に`allowProtoMethodsByDefault: true`を設定している環境では、リモートコード実行のリスクが極めて高いため、即座に設定を見直す必要があります。
フロントエンドエンジニアの皆様も、たとえサーバーサイドで実行されるコードであっても、テンプレートエンジンのセキュリティリスクは常に意識し、安全な設定と開発プラクティスを遵守することで、アプリケーションを脅威から守りましょう。最新のセキュリティ情報を継続的に収集し、適切な対策を講じることが重要です。