CSPとは
CSP(Content Security Policy、コンテンツセキュリティポリシー)は、ページが読み込んでよいスクリプト、画像、スタイルシートなどの取得元を、サーバーがブラウザに指示する仕組みです。Content-Security-Policy ヘッダーで指定します。
CSPが必要な理由
入力値の処理に不備があり、攻撃者のスクリプトがページに混入すると、XSSが成立します。CSPで許可した取得元以外のスクリプトを止めておけば、混入しても実行されず、外部への送信先も絞れます。
CSPは、根本対策の代わりにはなりません。出力時のエスケープなどの修正を行ったうえで、被害を小さくするための二重の備えとして使います。
CSPの仕組み
ヘッダーの値は、「ディレクティブ(制御する対象)と許可する取得元」を、セミコロンで区切って並べます。
| ディレクティブ | 制御する対象 |
|---|---|
default-src | 個別の指定がない読み込み全般の既定値 |
script-src | JavaScript |
style-src | CSS |
img-src | 画像 |
connect-src | fetchやXMLHttpRequestの通信先 |
object-src、base-uri | プラグインの埋め込み、baseタグによる基準URLの書き換え |
frame-ancestors | このページをiframeで埋め込める元(クリックジャッキング対策) |
取得元には、'self'(自サイト)、'none'(すべて禁止)、https://cdn.example.com のようなホスト名を書きます。インラインのスクリプトを個別に許可する 'nonce-...' や 'sha256-...' も使えます。frame-ancestors、base-uri、form-action は default-src では代用されないため、個別に書きます。
CSPの確認方法
開発者ツールの「ネットワーク」タブでレスポンスヘッダーを見るか、次のコマンドを実行します。
curl -s -D - -o /dev/null https://example.com/ | grep -i '^content-security-policy'
ポリシーに反した読み込みは、開発者ツールの「コンソール」に「Refused to load …」などの形で記録されます。Content-Security-Policy-Report-Only だけが出る場合は、まだ強制されていません。
CSPの設定例
いきなり強制すると、サイトの表示や機能が壊れることがあります。まず Content-Security-Policy-Report-Only で違反の記録だけを行い、コンソールの違反がなくなってから、強制の Content-Security-Policy に切り替えます。
Apache(.htaccess)の例です。
Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'"
nginxの例です。
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'" always;
WordPress(子テーマのfunctions.php)の例です。
add_action('send_headers', function () {
header("Content-Security-Policy-Report-Only: default-src 'self'; img-src 'self' data: https:; object-src 'none'; base-uri 'self'");
});
実際のサイトでは、解析タグや埋め込み地図などの外部サービスが違反として記録されます。必要なものだけを取得元に加えていきます。違反の報告を集めたい場合は、report-to や report-uri で送信先を指定します。
よくある間違いと注意点
script-srcに'unsafe-inline'や*、https:を入れると、XSSを止める効果がほとんど失われます。- 許可する取得元を並べる方式は、設計と維持が難しくなりがちです。MDNは、nonceやハッシュを使う方式を勧めています。
<meta http-equiv="Content-Security-Policy">では、frame-ancestorsやreport-uriが効かず、Report-Onlyも使えません。HTTPヘッダーで指定します。- Report-Onlyの中の
frame-ancestorsは無視されます。クリックジャッキング対策だけを先に行うなら、強制のContent-Security-Policy: frame-ancestors 'self'の1行から始められます。 - WordPressの管理画面はインラインスクリプトを多く使います。管理画面にまで強制する前に、動作を確かめます。
Webサイト セキュリティチェッカーで確認する
Webサイト セキュリティチェッカーは、Content-Security-Policyの有無と、script-src に 'unsafe-inline' などの弱い指定が残っていないかを診断します。Report-Onlyだけで強制されていない状態も、区別して示します。
関連用語
関連する用語
サイトの設定を無料で確認する
サイトのURLを入力するだけで、CSP などの設定状況を診断できます。Webサイト セキュリティチェッカー「Security Checker X」は、登録なしで使えます。









