Content-Security-Policy生成
サイトに CSP を導入したいが、何をどこに書けばよいか分からないときに。使っている外部サービスを選んで雛形を作り、Report-Only で試してから本番に移す流れを想定しています。
🔒 入力内容はお使いのブラウザ内だけで処理され、サーバーには送信されません。
よく使う外部サービス(プリセット)
チェックを入れると、そのサービスに必要なソースを該当ディレクティブに追加します。外すと、プリセット由来のソースだけを取り除きます。
ディレクティブ
ソースは空白区切りで入力します。キーワードは引用符付き('self' 'none' 'unsafe-inline' 'nonce-...' 'strict-dynamic')、ホストは https://example.com や *.example.com の形式です。空のディレクティブは出力しません。
既存の CSP を解析する
使い方
- サイトで使っている外部サービスにチェックを入れます。必要なソースが各ディレクティブに追加されます。
- 自社の CDN や API など、プリセットに無いソースは該当する欄に空白区切りで追加します。
- 「生成する」を押すと、HTTP ヘッダー、meta タグ、.htaccess、nginx の形式で出力され、推奨から外れる設定があれば上に表示されます。
- まず「Report-Only」で出力したものを設定し、ブラウザの Console やレポートで違反が出ないことを確認してから、本番の CSP に切り替えます。
ソースの書き方
| 書き方 | 意味 |
|---|---|
'self' / 'none' |
同じオリジンのみ許可 / 何も許可しない |
https://cdn.example.com / *.example.com |
そのホスト(サブドメインをまとめて)許可 |
data: blob: |
スキーム単位の許可 |
'unsafe-inline' |
インラインの script / style を許可。script-src では XSS 対策の効果がほぼ失われます |
'nonce-乱数' / 'sha256-ハッシュ' |
同じ nonce 属性、または内容のハッシュが一致するインライン要素だけ許可 |
'strict-dynamic' |
nonce や hash で許可したスクリプトが読み込む別のスクリプトも許可 |
frame-ancestors、base-uri、form-action は default-src を継承しないため、別に書きます。
nonce と 'unsafe-inline' の違い
'unsafe-inline' はページ内のスクリプトをすべて信用する設定で、攻撃者が差し込んだスクリプトも実行されます。nonce は、サーバーがページ生成のたびに作る合言葉を持つスクリプトだけを信用する設定で、攻撃者は事前に値を知れません。同じインラインスクリプトを許可する場合でも、nonce の方が守れる範囲が広くなります。nonce は暗号用の乱数から 128 ビット以上を作り、静的な HTML で毎回変えられない場合は hash を使います。
推奨する最低限の設定と理由
object-src 'none': 古いプラグイン経由の攻撃経路を閉じるためです。base-uri 'self': base タグを差し込まれると相対 URL の参照先をまとめて書き換えられるためです。frame-ancestors 'self': 他サイトの iframe に埋め込まれるクリックジャッキングを防ぐためです。両方ある場合は X-Frame-Options より CSP が優先されます。form-action 'self': フォームの送信先を差し替えて入力内容を盗む手口を防ぐためです。
注意
プリセットは各サービスの公開情報に基づく代表的なものです。サービス側の変更で不足することがあるため、導入後は Console の違反メッセージを確認してください。
よくある質問
CSP を入れたらサイトの表示が崩れました。
許可していないソースからの CSS、画像、スクリプトがブロックされています。ブラウザの開発者ツールの Console に「Refused to load ...」のようなメッセージと、必要なディレクティブが表示されるので、それを見て追加してください。本番に入れる前に Report-Only 版で一定期間運用し、違反を洗い出してから切り替えるのが安全です。
'unsafe-inline' を付ければ動くのですが、問題ありますか?
script-src に 'unsafe-inline' を付けると、ページ内に書かれた script や onclick 属性がすべて許可されます。攻撃者が注入したスクリプトも同じ扱いになるため、XSS を防ぐという CSP の主な目的が果たせません。インラインスクリプトが必要な場合は nonce か hash を使い、script-src からは 'unsafe-inline' を外すことを推奨します。style-src の 'unsafe-inline' は script-src ほど危険ではありませんが、できれば避けます。
meta タグと HTTP ヘッダーのどちらで設定すべきですか?
HTTP ヘッダーが基本です。meta タグでは frame-ancestors、report-uri、report-to、sandbox が使えず、meta タグより前に読み込まれたリソースには適用されません。サーバーの設定を触れない場合の代替手段として meta タグを使ってください。
nonce はどのように使いますか?
ページを生成するたびにランダムな値(nonce)を作り、ヘッダーの script-src に 'nonce-値' を書き、許可したい script タグに nonce="値" 属性を付けます。値はリクエストごとに変える必要があるため、静的な HTML では使えません。静的サイトでは代わりに hash('sha256-...')を使います。