リソース読み込み制限 - Content Security Policy (CSP)
ブラウザが読み込めるリソースの種類やオリジンを制限する HTTP ヘッダ。XSS の被害を大幅に軽減できる。
概念図
実例
スクリプトの読み込み元を制限
bash
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com画像は全オリジン許可、CSS はインライン許可
bash
Content-Security-Policy: default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'主要なディレクティブ
default-src: 他のディレクティブが指定されていない場合のフォールバックscript-src: JavaScript の読み込み元style-src: CSS の読み込み元img-src: 画像の読み込み元connect-src: XHR / Fetch / WebSocket の接続先frame-ancestors: このページを iframe に埋め込めるオリジン(クリックジャッキング対策)
モダンフレームワークとの現実的な課題
多くのフロントエンドフレームワークは、厳格な CSP と衝突する機能を内部的に使っています。
| フレームワーク | CSP との衝突ポイント | 影響するディレクティブ |
|---|---|---|
| Angular | デフォルトでインラインスタイルを動的生成。16+ では NgOptimizedImage が preconnect ヒントを自動挿入 |
style-src 'unsafe-inline' が必要 / connect-src に影響 |
| React | style 属性をオブジェクトで直接指定する設計でインラインスタイルが多用される。Next.js の <Script> はインラインスクリプトを生成する場合がある |
style-src 'unsafe-inline' / script-src に nonce が必要 |
| Vue | <style scoped> 自体は data 属性で安全だが、CSS-in-JS ライブラリがインラインスタイルを注入する |
style-src 'unsafe-inline' がライブラリ次第で必要 |
現実的な対応策
| 手法 | 概要 | 適するケース |
|---|---|---|
| nonce ベース CSP | リクエストごとにランダムな nonce を生成し script-src 'nonce-xxxx' で許可 |
SSR(Next.js / Nuxt / Angular SSR) |
| hash ベース CSP | 静的インラインスクリプトの SHA-256 ハッシュを CSP に記載 | SSG サイト |
strict-dynamic |
nonce 付きスクリプトから動的に読み込まれるスクリプトも自動許可 | SPA のチャンク読み込み |
style-src 'unsafe-inline' の許容 |
スタイルのインライン制限は XSS 防止効果が薄い(主な攻撃ベクタはスクリプト)。script-src を厳格にしつつ style-src は緩和する |
全般(現実的な妥協点) |
