「CSPは設定しただけで満足?」――XSSを無効化する現場の生存戦略
こんにちは。セキュリティチームのチーフです。
日々、国内外のインシデント事例を分析していると、「あぁ、またか」とため息が出る瞬間があります。それは、アプリケーション層でXSS(クロスサイトスクリプティング)の脆弱性が放置され、それを防ぐはずのCSP(Content-Security-Policy)が、ただの「お守り」のように形骸化しているケースです。
多くのエンジニアが「`script-src ‘self’`を設定したから大丈夫」と安心していますが、実際の攻撃者はそんな甘い設定の裏をかきます。今日は、現場のリアリティに基づいた「本当に効くCSP」の実装について、泥臭い知見を共有しましょう。
—
1. なぜ ‘self’ だけでは不十分なのか?
多くのエンジニアが陥る罠は、`script-src ‘self’`だけで済ませようとすることです。しかし、現代のWebアプリケーションには、JSONPエンドポイントや、意図せずアップロードされた画像ファイル(中にスクリプトを埋め込まれたSVGなど)が潜んでいることが多々あります。これらは`’self’`の範囲内とみなされ、攻撃者に悪用されます。
攻撃者が狙う盲点(PoCの視点)
攻撃者は、あなたが「安全だ」と信じているサーバー上のスクリプトを悪用します。例えば、`https://example.com/api/user?callback=alert(document.cookie)//` のようなURLにXSSの脆弱性があれば、`script-src ‘self’`はこれを防げません。
だからこそ、「信頼できないものは実行させない」というホワイトリスト主義を、nonce(ナンス)やhashを用いて強制する必要があるのです。
—
2. nonceを用いたモダンな防御術
nonce(Number used once)は、リクエストごとに生成されるランダムな文字列です。サーバー側で生成し、CSPヘッダーとHTMLタグの両方に同じ値を埋め込むことで、「このスクリプトはサーバーが意図して出力したものである」とブラウザに証明させます。
実装サンプル:PHPでの実装例
PHPでnonceを生成し、ヘッダーとスクリプトに反映するコードです。
CSPの実装例
—
3. Nginxでの設定と「運用上の注意」
インフラ側でポリシーを強制する場合、Nginxの設定ファイルでヘッダーを付与します。ただし、nonceは動的な値であるため、Nginx単体では完結しません。PHPやPythonなどのアプリケーション側で値を生成し、それをフロントエンドに渡す設計が必須です。
Nginx設定例(静的ポリシーの場合)
もしnonceが使えず、静的なハッシュ値を使う場合は、このように設定します。
CSPの基本設定
add_header Content-Security-Policy “default-src ‘self’; script-src ‘self’ ‘sha256-hash-value-here’; object-src ‘none’; frame-ancestors ‘none’;”;
※ `sha256-`の後の値は、スクリプトの中身をSHA256でハッシュ化したものです。インラインスクリプトの内容を変えるたびに修正が必要になるため、運用負荷は高いですが、nonceが使えないレガシーな環境での最後の砦です。
—
4. 現場で守るべき「3つの鉄則」
最後に、私がインシデント対応の現場で必ず確認するポイントをまとめました。
1. `unsafe-inline` は絶対に避ける
これを許容した時点で、CSPの防御力はゼロに等しいと考えてください。攻撃者に「どうぞ、お好きなスクリプトを注入してください」と言っているようなものです。
2. `report-uri` または `report-to` を設定せよ
CSP違反が発生した際、どこで誰が攻撃を試みているかを検知しなければ、防御は片手落ちです。監視エンドポイントにログを集約し、異常なアクセスを可視化しましょう。
3. `base-uri ‘none’` を忘れない
意外と見落とされがちですが、`
—
最後に:完璧を目指すより、まず「可視化」から
CSPは強力ですが、既存の巨大なアプリケーションにいきなり厳格な設定を適用すると、画面が真っ白になり、ユーザーからクレームの嵐が届くことになります。
まずは `Content-Security-Policy-Report-Only` ヘッダーを使って、「今のコードで何がブロックされるのか」をログとして収集することから始めてください。 壊れるリスクを恐れず、しかし慎重に、一段ずつ強固にしていく。それが、プロのエンジニアが歩むセキュリティの道です。
皆さんのシステムが、今日も安全であることを願っています。何か行き詰まったら、また相談してください。

コメント