【実務・中級編】AngularJSのテンプレートインジェクションとサンドボックス回避 – アプリケーションセキュリティ & 安全な開発防御ガイド

レガシーの呪縛:AngularJSサンドボックス回避と、現代のフロントエンドに潜む「動的評価」の罠

現場でインシデント対応をしていると、いまだに「数年前の負債」という名のAngularJS(1.x系)アプリケーションに出くわすことがある。当時の開発者は「フレームワークが自動でエスケープしてくれるから安心だ」と信じて疑わなかっただろう。だが、セキュリティの世界に「絶対」はない。

今日は、多くのエンジニアが「魔法」だと思っているテンプレートエンジンの裏側、特にAngularJSのサンドボックスがなぜ崩壊し、現代のフレームワークでもなぜ「動的評価」が危険なのかを、泥臭い実務の視点から紐解いていく。

—

1. AngularJSのサンドボックスは「箱」ですらなかった

AngularJS 1.x系において、{{ ... }} という構文は単なる表示用ではない。ブラウザ側でJavaScriptのサブセットを評価するエンジンが動いている。脆弱性の核心は、この評価エンジンに「サンドボックス」を設けて、危険な関数(windowやconstructorなど)へのアクセスを制限しようとした点にある。

しかし、攻撃者はこの制限を「バイパスするパズル」として楽しんだ。有名なペイロードを見てみよう。

PoC:サンドボックス回避の典型例

// 古いAngularJS環境で実行可能な悪意ある式
{{
constructor.constructor(‘alert(document.domain)’)()
}}

この式がなぜ通るのか? constructor プロパティを辿ることで、JavaScriptの Function コンストラクタに到達し、サンドボックスの外側で任意のJSコードを実行できてしまうからだ。開発者が「ユーザー入力値をテンプレートにそのまま埋め込んだ」瞬間、この悪夢が始まる。WAFで alert を弾いたところで、eval や String.fromCharCode を駆使すればいくらでも難読化される。

—

2. 「自動エスケープ」の限界と現代の脆弱性

ReactやVueといった現代のフレームワークは、デフォルトでDOMエスケープを行うため、単純なXSSは劇的に減った。しかし、インシデント現場で見かけるのは「自動エスケープを意図的に無効化した箇所」の脆弱性だ。

  • dangerouslySetInnerHTML (React)
  • v-html (Vue)
  • ng-bind-html (AngularJS)

これらは「開発者が安全性を保証する」という前提で用意されたバックドアだ。バックエンドから返ってきた信頼できないHTMLをここに流し込めば、フレームワークの防御壁は一瞬で無効化される。

—

3. 実践:セキュアな設計と実装の防波堤

では、我々はどう戦うべきか。結論はシンプルで、「テンプレートエンジンに動的なコード評価をさせない」ことと「出力時のコンテキストに応じたサニタイズ」の二段構えだ。

防御策A:CSP(Content Security Policy)による封じ込め

JavaScriptのインライン実行を禁止する。これが現代のXSS対策における最強の防波堤だ。

Nginx設定例:

信頼できるドメイン以外のスクリプト実行を禁止
‘unsafe-eval’ を含めないことがAngularJS対策の要
add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ https://trusted.cdn.com; object-src ‘none’;”;

防御策B:DOMPurifyによるHTMLサニタイズ

どうしてもHTMLをレンダリングする必要がある場合は、フレームワーク任せにせず、信頼性の高いライブラリでクリーニングする。

JavaScript 実装サンプル:

import DOMPurify from ‘dompurify’;

// ユーザー入力を受け取った直後にサニタイズする
const untrustedInput = ““;
const cleanHTML = DOMPurify.sanitize(untrustedInput);

// 安全なHTMLのみをDOMに挿入
document.getElementById(‘content’).innerHTML = cleanHTML;

—

4. 最後に:セキュリティは「疑う」ことから始まる

私が駆け出しの頃、先輩に言われた言葉がある。「フレームワークのドキュメントを読め。そして、そのフレームワークがどうやって『あなたのコード』を操作しているか、その裏側の挙動を疑え」。

AngularJSのテンプレートインジェクションは、まさに「便利な機能が、いかに攻撃の踏み台にされやすいか」を象徴する事例だ。最新のフレームワークを使っていても、ロジックを組む際に「もしこの変数が攻撃者に制御されていたら、ブラウザはどう解釈するか?」と一歩立ち止まって考えてほしい。

もし今、手元にレガシーなAngularJSアプリがあるなら、まずはCSPを厳格化し、ng-bind-html を使っている箇所を全検索することから始めてくれ。それが、大規模なデータ漏洩を防ぐための、最も泥臭く、そして最も確実な第一歩だ。

何か技術的な壁にぶつかったら、またいつでも聞いてくれ。現場の最前線で戦う君たちを、私は常にサポートしている。

コメント

タイトルとURLをコピーしました