XSSの牙城を崩す:Content Security Policy (CSP) による鉄壁の防御設計
Webアプリケーションのセキュリティ、特にクロスサイトスクリプティング(XSS)の脅威は、もはや古典的でありながら、未だに多くのシステムを蝕む根深い問題だ。CVEとして日々報告される脆弱性の多くは、このXSSの範疇に収まるか、その派生形である。我々が日々格闘しているのは、単なるコードのバグではない。そこには、HTTPプロトコルの仕様の隙間を突く巧妙な手法、ブラウザのレンダリングエンジンの挙動を逆手に取るトリッキーな攻撃、そして何より、攻撃者の「常識」を覆すような発想が潜んでいる。
本稿では、OWASP Top 10の最前線に立ち続けるXSS対策の切り札、Content Security Policy(CSP)に焦点を当てる。単なる「設定しておけば安心」という甘い言葉に騙されてはならない。真のセキュリティアーキテクト、チーフホワイトハッカー、そしてテックリードが実践すべき、CSPの設計思想、厳格なポリシー適用のためのディープな技術、そして最新の動向について、現場の生々しい知見と、攻撃者の視点から徹底的に掘り下げていく。
CSPの核心:信頼の連鎖を断ち切る「許可リスト」思想
XSS攻撃の根源は、信頼されていない(あるいは信頼性が低い)ソースからのスクリプトが、ユーザーのブラウザ上で実行されてしまうことにある。攻撃者は、この「信頼」の隙間を縫って、悪意あるJavaScriptを注入し、セッションハイジャック、情報窃取、フィッシングサイトへのリダイレクトといった、おぞましい所業を働く。
CSPは、この問題を根本から解決するために、「デフォルト拒否」の原則に基づき、明示的に許可されたリソースのみをロード・実行できるようにすることで、ブラウザの挙動を制御する。これは、従来のような「ブラックリスト」(悪意あるものを列挙して排除する)アプローチの限界を突破し、「ホワイトリスト」(安全なものを列挙して許可する)という、より堅牢なセキュリティモデルを実装するための強力なメカニズムだ。
HTTPレスポンスヘッダーに `Content-Security-Policy` を追加することで、ブラウザにどのようなリソースをどこからロードして良いかを指示する。
Content-Security-Policy: default-src ‘self’; script-src ‘self’; object-src ‘none’;
このシンプルな例でも、その意図は明確だ。
- `default-src ‘self’`: 全てのリソース(スクリプト、スタイルシート、画像、フォントなど)のデフォルトの取得元を、同一オリジン(`’self’`)に制限する。
- `script-src ‘self’`: JavaScriptの実行元を、同一オリジンに限定する。
- `object-src ‘none’`: `
しかし、現実のWebアプリケーションは、CDNからライブラリを読み込んだり、外部APIを利用したりと、同一オリジンだけでは完結しない。ここで、CSPの真価が問われる。
攻撃者の盲点を突く:CSPディレクティブの「粒度」と「賢い」活用
CSPの強力さは、そのディレクティブの豊富さと、それらを組み合わせることで実現できる「粒度の細かい」制御にある。攻撃者は、どこか一点の緩みを見つけて侵入しようとする。我々は、その一点たりとも残さないための、精密な設計が求められる。
1. `script-src` の厳格化と `nonce` の活用
インラインスクリプトや`eval()`によるスクリプト実行は、XSSの温床だ。これを防ぐために、`script-src` ディレクティブで `’unsafe-inline’` や `’unsafe-eval’` を排除するのは基本中の基本。
Content-Security-Policy: default-src ‘self’; script-src ‘self’ https://cdn.example.com;
これだけでも、外部CDNからのスクリプト読み込みは許可されるが、HTML内に直接記述された `