CSP Level 3の「strict-dynamic」で、フロントエンドの悪夢を終わらせる
現場でセキュリティを語る時、一番の敵は「利便性と安全性の間の妥協」だ。
「このライブラリを動かすために、タグのドメイン制限を緩めよう」……そんな妥協を積み重ねた結果、CSP(Content Security Policy)が単なる飾りになっている現場を山ほど見てきた。
今日は、現代の複雑なフロントエンド構成において、CSPを「面倒な足かせ」から「最強の盾」に変えるための切り札、strict-dynamicについて深掘りする。
---
なぜ従来のCSPは「現場」で破綻するのか
従来のCSPは、ドメイン単位のホワイトリスト(script-src 'self' example.com 等)に依存していた。しかし、今のWeb開発はそう単純じゃない。
CDNから配信される巨大なライブラリが、実行時に動的に別のスクリプトを読み込む(いわゆるダイナミックインポート)。この時、親スクリプトを許可していても、生成された子スクリプトがホワイトリストにないドメインなら、ブラウザは即座にブロックする。
結果、エンジニアは泣く泣く 'unsafe-inline' を許可し、XSS(クロスサイトスクリプティング)の入り口を全開にしてしまう。これが今の現場の現実だ。
strict-dynamic が解決する「動的読み込み」の盲点
strict-dynamic は、このジレンマを解消する。
「信頼されたスクリプトがロードしたスクリプトは、たとえドメインが異なっても信頼する」という考え方だ。これにより、ドメインのホワイトリスト管理という泥沼から解放される。
攻撃者が狙う盲点:CSPをバイパスするPoC
攻撃者は、あなたが「どうせライブラリの読み込みでCSPを緩めているだろう」と踏んで、以下のようなペイロードを狙う。
これに対し、strict-dynamic と nonce(使い捨てトークン)を組み合わせれば、攻撃者がいかに巧妙なスクリプトを注入しようとも、HTMLの中に「正しいnonce」が含まれていない限り、ブラウザは一切の実行を拒否する。
---
実装:コピペで動くセキュアな構成
実務では、Nginx側のヘッダー設定と、サーバーサイドでのNonce生成がセットになる。
1. Nginx設定(セキュリティヘッダー)
まずは、CSPヘッダーを厳格に定義する。'unsafe-inline' は nonce があれば無視される仕組みを利用する。
Nginxの設定例
'strict-dynamic' を指定することで、信頼されたスクリプトからの動的ロードを許可
'nonce-...' は動的に生成するため、ここではプレースホルダーとして扱う
add_header Content-Security-Policy "default-src 'self'; script-src 'nonce-RANDOM_NONCE' 'strict-dynamic'; object-src 'none'; base-uri 'self';" always;
2. バックエンド(PHP)でのNonce生成
リクエストごとに一意の文字列を生成し、テンプレートとヘッダーの両方に渡す。
console.log('このスクリプトは実行されます');
// ここで動的に読み込まれるライブラリも自動的に信頼される
";
?>
---
プロフェッショナルとしての注意点
この設計を採用する際、一つだけ絶対に忘れてはならないことがある。「古いブラウザの挙動」だ。
strict-dynamic は CSP Level 3 の仕様であり、古いブラウザ(IEなど)はこれを無視して、従来のドメイン・ホワイトリストを優先する。そのため、堅牢性を担保するには「フォールバック」の設定が必須だ。
推奨設定例
script-src 'nonce-RANDOM' 'strict-dynamic' 'self' https:;
このように、'self' や https: を並記しておくことで、最新ブラウザでは strict-dynamic が効き、古いブラウザでは従来のドメイン制約が働く多層防御の形になる。
まとめ:泥臭い検証の先にある安心
セキュリティは「設定して終わり」ではない。
strict-dynamic を導入すると、これまで動いていたサードパーティ製プラグインが突然動かなくなることがある。それは「これまで脆弱性を放置していた」という事実を突きつけられた瞬間だ。
その時、「動かなくなったから設定を戻そう」と妥協するのか、あるいは「なぜそのスクリプトは信頼できないドメインから読み込まれているのか?」と精査するのか。この姿勢の差が、インシデントに強い組織と、いつか事故を起こす組織の分かれ道になる。
コードはシンプルに、防御は徹底的に。それがプロの仕事だ。
コメント