CSPの「strict-dynamic」でXSSを根絶する:ホワイトハッカーが教える現代的な防御戦略
現場でインシデント対応をしていると、「CSP(Content Security Policy)を設定しているのにXSSを突破された」という嘆きを耳にすることがあります。その原因の多くは、unsafe-inlineを安易に許可していたり、ホワイトリスト方式の運用が破綻して、結局ガバガバな設定になっているケースです。
今日は、現代のWebアプリケーションにおいて「XSSを実質無効化する」ための最強のカード、strict-dynamicについて解説します。教科書的な説明は抜きにして、なぜこれを使うべきなのか、どう実装すれば現場で動くのか、その核心に切り込みましょう。
—
1. なぜ従来のCSPは「負け戦」なのか
かつてのCSPは、信頼するドメインを羅列するホワイトリスト方式(script-src 'self' https://trusted.com など)が主流でした。しかし、これには致命的な欠点があります。
- ホワイトリストの崩壊:
trusted.com上にたまたま存在していた古いJSONPエンドポイントや、AngularJS等のライブラリを攻撃者に悪用され、結局インジェクションを許してしまう。 - 管理コストの爆発: CDNや外部スクリプトが増えるたびにヘッダーを修正する必要があり、運用が耐えられなくなる。
そこで登場したのが、「信頼されたスクリプトから動的に生成されたスクリプトは、たとえ外部からであっても実行を許可する」という考え方、strict-dynamicです。
—
2. strict-dynamic の仕組みとPoCの視点
攻撃者が狙うのは、HTML内に埋め込まれた や、属性ベースのイベントハンドラー(onmouseover等)です。
strict-dynamic を導入すると、ブラウザは「信頼されたソース(nonceやハッシュが付与されたスクリプト)が生成した子要素のみを信頼する」ようになります。これにより、攻撃者が外部から注入した野良スクリプトは、どんなに頑張っても実行されません。
攻撃者から見た「突破不能な壁」
攻撃者が https://attacker.com/malicious.js をロードしようとしても、それが信頼されたスクリプト(nonceを持つ親スクリプト)によって動的に生成されたものでなければ、ブラウザは即座にブロックします。これが「防弾」と呼ばれる理由です。
—
3. 実装のベストプラクティス(コピペ用サンプル)
strict-dynamic を使う際は、必ず nonce(毎回ランダムに生成される文字列)を併用します。
PHPでのヘッダー出力例
まずはバックエンドでnonceを生成し、ヘッダーとHTMLの両方に埋め込みます。
なぜこれで安全なのか(後方互換性の魔法)
- モダンブラウザ:
strict-dynamicを解釈し、'unsafe-inline'やhttps:を無視して、nonceが一致するスクリプトのみを信頼します。 - 古いブラウザ:
strict-dynamicを解釈できないため、フォールバックとして指定した'unsafe-inline'やhttps:を参照します。これにはリスクが伴いますが、少なくとも「動かない」よりは「最低限のガードがある」状態を維持できます。
—
4. インフラ側で締め上げる(Nginx設定)
アプリケーション側だけでなく、WAFやリバースプロキシでもCSPを制御しておくのがプロの流儀です。Nginxであれば以下のように設定します。
Nginx設定ファイル
add_header Content-Security-Policy “script-src ‘nonce-RANDOM_NONCE_PLACEHOLDER’ ‘strict-dynamic’ ‘unsafe-inline’ https:; object-src ‘none’;”;
※実際には、nginxの sub_filter モジュール等を使って、動的に生成したnonceをレスポンス本文に注入する工夫が必要です。
—
5. 現場のエンジニアへ送るアドバイス
最後に、現場で運用する上での注意点を一つ。
strict-dynamic を導入すると、インラインイベントハンドラー()が動かなくなります。これは「セキュリティ向上の代償」として受け入れ、すべてのロジックをJSファイル(addEventListener)に切り出すリファクタリングを断行してください。
最初は面倒に感じるでしょうが、XSSという「終わりのない穴埋め作業」から解放されるコストだと思えば安いものです。
セキュリティは「完璧」を目指すものではなく、「攻撃者が割に合わないと判断するコスト」を積み上げるものです。strict-dynamic はその中でも、最も費用対効果の高い防壁の一つ。今日からあなたのプロジェクトでも導入を検討してみてください。
何かあればいつでも相談に乗ります。堅牢なシステムを、共に作っていきましょう。
コメント