moldspoon

🛡️ CSPビルダー

Content-Security-Policy(CSP)は、ブラウザに「どこから読み込んだリソースなら実行してよいか」を伝えるヘッダーです。XSSが発生しても攻撃コードの実行を止められる、最後の砦にあたります。主要なディレクティブごとに許可するソースを選ぶだけで、そのまま貼り付けられるCSPを組み立てます。

プリセットから始める

厳格(strict)

default-src 'none' からはじめ、必要なものだけ自サイトに限定して開けます。新規サイトはここから調整するのが理想です。

一般的なSPA

React / Vue などのSPA向け。CSS-in-JSのために style-src だけ 'unsafe-inline' を許し、画像とWorkerに blob: を開けています。

緩め(レガシー移行用)

既存サイトにいきなり厳しいCSPを入れると壊れます。まずこの内容を Report-Only で流し、違反レポートを見ながら締めていく用途向けです。そのまま本番の強制ポリシーにしないでください。

ディレクティブの設定

ディレクティブ名をクリックすると、その項目のオン・オフを切り替えられます。ソースが1つも選ばれていないディレクティブは出力に含まれません。

default-src

他のディレクティブが未指定のときの既定値。まずここを絞り込むのが基本です。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
default-src 'self'
script-src

JavaScriptの読み込み元。XSS対策として最も重要な項目です。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
script-src 'self'
style-src

CSSの読み込み元。CSS-in-JSを使う場合は 'unsafe-inline' が必要になることがあります。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
style-src 'self' 'unsafe-inline'
img-src

画像の読み込み元。Base64画像を使うなら data: が必要です。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
img-src 'self' data: blob:
connect-src

fetch / XHR / WebSocket / EventSource の接続先。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
connect-src 'self'
font-src

Webフォントの読み込み元。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
font-src 'self' data:
frame-src

iframeとして埋め込むことを許可する読み込み元。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
frame-src 'self'
frame-ancestors

自サイトをiframeに埋め込める側の指定。クリックジャッキング対策になります。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
frame-ancestors 'none'
base-uri

<base>タグで指定できるURL。'self' に固定すると相対URLの乗っ取りを防げます。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
base-uri 'self'
form-action

フォームの送信先。外部への送信を防ぎます。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
form-action 'self'
object-src

<object> / <embed> の読み込み元。'none' の指定を強く推奨します。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
object-src 'none'
media-src

<audio> / <video> の読み込み元。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
media-src 'self'
worker-src

Worker / SharedWorker / ServiceWorker の読み込み元。

使う
'self'
'none'
'unsafe-inline'
'unsafe-eval'
data:
blob:
https:
worker-src 'self' blob:

生成されたポリシー

Report-Only で出力する

オンにすると Content-Security-Policy-Report-Only として出力します。ブラウザは違反を検出しても実際にはブロックせず、コンソールとレポート送信先に記録するだけになります。既存サイトに導入するときは、まずこちらで様子を見てください。

13件のディレクティブを出力しています。

ポリシー値のみ
default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; font-src 'self' data:; frame-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; media-src 'self'; worker-src 'self' blob:
✅ コピーしました!
HTTPヘッダー形式

Webサーバーやアプリケーション側でこのヘッダーを付与します。meta タグより優先度が高く、frame-ancestors も有効なため、可能な限りこちらを使ってください。

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; font-src 'self' data:; frame-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'; media-src 'self'; worker-src 'self' blob:
✅ コピーしました!
meta タグ形式

HTMLの<head>内、できるだけ先頭に置いてください。metaタグでは frame-ancestors / report-uri / sandbox が無効なため、出力から frame-ancestors を除いています。クリックジャッキング対策が必要な場合はHTTPヘッダー形式を使ってください。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; connect-src 'self'; font-src 'self' data:; frame-src 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; media-src 'self'; worker-src 'self' blob:">
✅ コピーしました!

設定の診断

⚠️ style-src に 'unsafe-inline' が含まれています

スクリプトほどではありませんが、CSSインジェクションによる情報の抜き取りや画面偽装の余地が残ります。CSS-in-JSの都合でどうしても必要な場合を除き、外部CSSファイルに寄せてください。

nonce と hash の使い方

インラインスクリプトをどうしても残したい場合、'unsafe-inline' の代わりに noncehash を使います。どちらも「このスクリプトだけは許可する」とピンポイントで指定する仕組みなので、攻撃者が注入したスクリプトは実行されません。

nonce(ノンス)

リクエストごとにサーバー側でランダムな値(16バイト以上、Base64推奨)を生成し、ヘッダーとタグの両方に同じ値を書きます。

Content-Security-Policy: script-src 'self' 'nonce-r4nd0mV4lu3'

<script nonce="r4nd0mV4lu3">
  // このスクリプトだけ実行が許可される
</script>

値を毎回変えることが必須です。固定値やページキャッシュへの埋め込みは、攻撃者に値を知られるため意味がなくなります。静的ホスティングのようにリクエストごとの生成ができない環境では、nonce は使えません。

hash(ハッシュ)

スクリプトの中身そのもののハッシュ値を許可リストに書きます。中身が固定のインラインスクリプト向けで、静的サイトでも使えます。

Content-Security-Policy: script-src 'self' 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='

<script>alert('Hello, world.');</script>

対象は<script>タグの中身そのもの(前後の改行や空白も含む)です。sha256 / sha384 / sha512 が使えます。ハッシュ値は、違反時にブラウザのコンソールに表示される値をそのまま貼るのが確実です。スクリプトを1文字でも変えると値が変わるので、ビルド時に自動生成する運用にしてください。

併記したときの挙動

nonce または hash が指定されている場合、対応ブラウザは 'unsafe-inline' を無視します。そのため、古いブラウザ向けの保険として 'unsafe-inline' を残す書き方は成立します。逆に、'strict-dynamic' を併記すると、nonce付きスクリプトが動的に読み込んだスクリプトも許可され、ホスト名の許可リストは無視されます。

関連ツール

🛡️ セキュリティヘッダー診断

URLを入力すると、実際に配信されているCSPやHSTS、X-Frame-Options などの設定を採点します。作ったCSPが正しく反映されたかの確認にどうぞ。

※ 入力内容はすべてブラウザ内(お使いの端末のJavaScript)で処理しており、サーバーへ送信・保存することは一切ありません。

※ 生成したポリシーは、必ずステージング環境や Report-Only で動作確認してから本番へ適用してください。CSPは設定を誤るとサイトの機能が動かなくなります。

※ 本ツールは主要なディレクティブのみを扱います。report-to / upgrade-insecure-requests / sandbox などが必要な場合は、生成結果に手で追記してください。

こんなツールをこれからも作っていきます。もしこれは!と思っていただけましたら、シェア・応援していただけると嬉しいです!😀

X (旧Twitter)

0

Facebook

LINE

0

はてブ

リンクコピー

✅ コピーしました!