結論(CSP違反の報告先)
CSP違反の報告先とは、Content Security Policyに違反した読込や実行をブラウザがブロックしたとき、その内容を自動送信(違反レポート)させる送り先のことです。CSPの report-uri(旧方式)または report-to(新方式)で指定し、report-to を使う場合はエンドポイント名とURLを対応付ける Reporting-Endpoints ヘッダーも必要です。レポートを受け取ると、設定ミスで正当な機能が壊れていないか、XSSの試行や不正なスクリプト注入がないかを把握できます。
この記事のポイント
- report-uri は旧方式で非推奨ですが広く動作し、report-to は Reporting API を使う新方式です。移行期間は両方の併記が推奨です。
- report-to に書くのはURLではなくエンドポイント名で、Reporting-Endpoints(旧 Report-To)ヘッダーがないと何も送信されません。
- report-uri・report-to はmeta CSPでは無視されるため、レスポンスヘッダーでの配信が必須です。
- 違反レポートは外部入力であり、閲覧URLも含むため、保存・表示時の無害化と保存期間・アクセス権限の管理が必要です。
- セキュリティAIチェッカーは強制CSPヘッダーに有効な報告先があれば○、なければ△、強制CSPヘッダーがなければ対象外と判定します。
| 診断項目名 | CSP違反の報告先 |
|---|---|
| 項目ID | headers.csp-reporting |
| 分類 | コンテンツセキュリティポリシー(CSP) |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V3.4.7(L3:CSPが違反の報告先を指定していること)、OWASP WSTG-CONF-12(report-to と Reporting-Endpoints の不一致を弱点として列挙)、W3C CSP Level 3 §6.5(report-uri / report-to)、W3C Reporting API |
CSP違反の報告先とは
CSP違反の報告先とは、Content Security Policy(CSP)に違反した読込や実行をブラウザがブロックしたとき、その内容を自動で送信させる送り先(違反レポートの受信先)のことです。CSPの report-uri または report-to ディレクティブで指定します。
Reporting-Endpoints: csp-endpoint="https://report.example.lg.jp/csp"
Content-Security-Policy: default-src 'self'; report-uri https://report.example.lg.jp/csp; report-to csp-endpoint
違反レポートを受け取ることで、次のことが可能になります。
- 正当な機能がCSPで壊れていないかの把握(設定ミスの早期発見)
- XSSの試行や、改ざんされたページ・不正な拡張機能によるスクリプト注入の兆候の検知
- CSP厳格化(
'unsafe-inline'の除去など)の影響範囲の事前確認
セキュリティAIチェッカーのこの項目は、強制されているCSPヘッダーに、実際にレポートが送られる報告先が設定されているかを確認します。CSPがレスポンスヘッダーで強制されているかどうかは「CSPがレスポンスヘッダーで強制されている」で確認します。
report-uri と report-to の違い(2つの指定方法)
1. report-uri(旧方式・非推奨だが広く動作)
Content-Security-Policy: default-src 'self'; report-uri https://report.example.lg.jp/csp
- 報告はPOSTで、
Content-Type: application/csp-reportのJSON(トップレベルにcsp-report)として送られます。 - CSP3とMDNは
report-uriを非推奨とし、report-toに対応したブラウザでは、report-toがあればreport-uriは無視されると説明しています。
2. report-to(新方式・Reporting APIを利用)
Reporting-Endpoints: csp-endpoint="https://report.example.lg.jp/csp"
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
report-toに書くのはURLではなく、エンドポイント名です。- 名前とURLの対応は、別の
Reporting-Endpointsレスポンスヘッダー(旧方式はReport-Toヘッダー)で定義する必要があります。この対応付けがないと、ブラウザは送り先が分からず、何も送信しません。 - 報告は
application/reports+jsonで送られます。 - MDNによれば、
Reporting-EndpointsのURLは安全な(HTTPS等の)URLである必要があり、そうでないエンドポイントは無視されます。
| 比較 | report-uri | report-to |
|---|---|---|
| 書く値 | 報告先のURL | エンドポイント名 |
| 追加で必要なヘッダー | なし | Reporting-Endpoints(旧 Report-To) |
| 送信形式 | application/csp-report | application/reports+json |
| 位置付け | 非推奨(ただし広く動作) | 新方式(Reporting API) |
推奨は report-uri と report-to の併記
MDNとCSP3は、移行期間中は両方を指定することを推奨しています。
Reporting-Endpoints: csp-endpoint="https://report.example.lg.jp/csp"
Content-Security-Policy: default-src 'self'; report-uri https://report.example.lg.jp/csp; report-to csp-endpoint
CSP違反の報告先を設定するときの注意点(仕組み)
meta要素では使えない
report-uri・report-to は、meta CSPでは無視されます。また、Content-Security-Policy-Report-Only ヘッダーはmeta要素では使えません。報告機能を使うには、レスポンスヘッダーでの配信が必須です。
Report-Onlyとの関係
Content-Security-Policy-Report-Only は、違反を報告するだけで遮断しないヘッダーで、新しいポリシーの試験に使います。OWASPチートシートは、強制ポリシーとReport-Onlyを同時に使えると説明しています。報告先がなければ、Report-Only自体が意味を持ちません。
CSP違反の報告先についてよくある誤解
- 「
report-toを書いたので報告される」:Reporting-Endpoints(またはReport-To)ヘッダーで名前を定義していなければ送られません。WSTG-CONF-12もこの不一致を確認項目に挙げています。 - 「報告内容は信頼できる」:レポートはブラウザから送られる外部入力です。MDNは、レポート(特に
script-sample)は攻撃者が制御し得るため、保存・表示時に無害化するよう注意しています。
CSP違反の報告先の診断基準(セキュリティAIチェッカー)
取得対象
トップページの最終応答のレスポンスヘッダーのうち、次の3つを評価します。
Content-Security-Policy(強制ポリシー)Reporting-EndpointsReport-To
meta CSPは報告ディレクティブを持てないため対象外です。report-uri・report-to は、値を伴うディレクティブとして、ヘッダー値の先頭または ;・, の直後にあるものを検出します。CSPヘッダーが複数本あり、カンマで連結された2本目以降のポリシーにだけ報告先がある場合も検出します。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 強制CSPに report-uri がある、または report-to があり、Reporting-Endpoints か Report-To ヘッダーも存在する | 1点 |
| △ 要確認(warn) | 強制CSPに報告先がない、または report-to はあるがエンドポイントを定義するヘッダーがない | 1×0.45=0.45点 |
| 対象外(na) | 強制CSPヘッダーがない(metaのみ・Report-Onlyのみ・CSPなし) | 採点に計上しない |
- 重みが1と小さいのは、報告先の有無が直接の脆弱性ではなく、運用監視の品質に関わる項目だからです(ASVSでもL3要件)。
- エンドポイント名と
Reporting-Endpoints内の名前が一致しているか、報告先のURLが応答するかまでは確認しません。
自治体サイトでの判定例
| レスポンスヘッダー | 判定 |
|---|---|
CSPに report-uri https://…/csp | ○ |
Reporting-Endpoints: csp="https://…" + CSPに report-to csp | ○ |
CSPに report-to csp のみ(Reporting-Endpointsなし) | △ |
| CSPに報告ディレクティブなし | △ |
| meta CSPのみ | 対象外 |
CSP違反の報告先がないとどんなリスクがあるか
- 攻撃・改ざんの見逃し:XSSの試行や、不正なスクリプト挿入(改ざん、悪性の外部タグ)がCSPでブロックされても、報告がなければ管理者は気づけません。ブロックされなかった別の経路の存在に気づく機会も失います。
- 正当な機能の停止に気づかない:外部サービスの配信ドメインの変更などで、地図や申請フォームの一部がCSPにより静かに動かなくなっても、住民からの問い合わせで初めて判明することになります。
- 厳格化が進まない:影響が測れないため、
'unsafe-inline'の除去などの改善に踏み出せず、弱いCSPのまま固定化しがちです。
CSP違反の報告先の設定方法(Apache・nginx・IIS・Next.js)
設定と運用の手順
- 受信先を用意:自前の受信スクリプト(POSTされたJSONを記録)か、CSPレポート収集のSaaSを用意します。HTTPSで受け付けます。
- まずReport-Onlyで有効化:新しいポリシーを試す際に、報告先を付けて配信します。
- 強制ポリシーにも付与:
report-uriとreport-toを併記します。 - 運用:レポートを定期的に確認し、件数の急増やブロックされた外部ドメインを点検します。拡張機能由来のノイズ(
chrome-extension:等)は集計から除外します。
Apache(.htaccess)
<IfModule mod_headers.c>
Header always set Reporting-Endpoints "csp-endpoint=\"https://www.example.lg.jp/csp-report.php\""
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; report-uri https://www.example.lg.jp/csp-report.php; report-to csp-endpoint"
</IfModule>
nginx
add_header Reporting-Endpoints 'csp-endpoint="https://www.example.lg.jp/csp-report"' always;
add_header Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; report-uri https://www.example.lg.jp/csp-report; report-to csp-endpoint" always;
IIS
<add name="Reporting-Endpoints" value="csp-endpoint="https://www.example.lg.jp/csp-report"" />
<add name="Content-Security-Policy" value="default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; report-uri https://www.example.lg.jp/csp-report; report-to csp-endpoint" />
Next.js(Vercel)
// next.config.js
const csp = "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; report-uri /api/csp-report; report-to csp-endpoint";
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [
{ key: 'Reporting-Endpoints', value: 'csp-endpoint="https://www.example.lg.jp/api/csp-report"' },
{ key: 'Content-Security-Policy', value: csp },
],
}];
},
};
受信側のルートでは、application/csp-report と application/reports+json の両方を受け付けます。
受信スクリプト(PHPの最小例)
<?php
// csp-report.php:サイズ上限を設け、内容は表示せず記録のみ
$body = file_get_contents('php://input', false, null, 0, 65536);
if ($body !== false && $body !== '') {
$line = date('c') . "\t" . str_replace(["\r", "\n"], ' ', $body) . "\n";
file_put_contents(__DIR__ . '/../logs/csp.log', $line, FILE_APPEND | LOCK_EX);
}
http_response_code(204);
ログはWeb公開領域の外に置き、管理画面で表示する場合は必ずエスケープしてください。
運用上の注意点
- 大規模サイトでは大量のレポートが届きます。受信側にサイズ制限・レート制限を設け、ディスクを圧迫しないようにします。
- レポートには閲覧ページのURLが含まれます。URLに個人情報を含めない設計と、ログの保存期間・アクセス権限の管理が必要です。
- 外部SaaSに送る場合は、委託先としての取扱い(個人情報保護・契約)を確認します。
設定後の確認方法
curl -sI https://www.example.lg.jp/ | grep -iE '^(content-security-policy|reporting-endpoints|report-to):'
CSPに report-uri または report-to があり、report-to を使う場合は Reporting-Endpoints(または Report-To)も返っていることを確認します。ブラウザの開発者ツール(Chromeの「アプリケーション」→「Reporting API」等)で、レポートの送信状況を確認できる場合があります。
よくある質問(FAQ)
report-uri と report-to はどちらを使えばよいですか?
移行期間中は両方を指定することが、MDNとCSP3で推奨されています。report-to に対応したブラウザでは report-to があれば report-uri は無視されるため、併記しても二重には送られません。
CSPに report-to を書いたのにレポートが届かないのはなぜですか?
report-to に書くのはエンドポイント名で、名前とURLの対応を Reporting-Endpoints(旧方式は Report-To)ヘッダーで定義していないと、ブラウザは送り先が分からず送信しません。また Reporting-Endpoints のURLはHTTPS等の安全なURLである必要があります。
meta要素のCSPで報告先を指定できますか?
できません。report-uri・report-to はmeta CSPでは無視され、Content-Security-Policy-Report-Only ヘッダーもmeta要素では使えません。報告機能を使うにはレスポンスヘッダーで配信する必要があります。
CSP違反の報告先がないと危険ですか?
報告先の有無は直接の脆弱性ではなく、運用監視の品質に関わる項目です。そのためセキュリティAIチェッカーでは重み1・重大度lowとしています。ただし報告がないと、攻撃や改ざんの試行、正当な機能の停止に気づけません。
違反レポートの内容はそのまま管理画面に表示してよいですか?
表示前に必ずエスケープしてください。レポートはブラウザから送られる外部入力で、特に script-sample は攻撃者が制御し得るとMDNが注意しています。ログはWeb公開領域の外に置きます。
レポートが大量に届いて困る場合はどうすればよいですか?
受信側にサイズ制限・レート制限を設け、ディスクを圧迫しないようにします。拡張機能由来のノイズ(chrome-extension: など)は集計から除外し、件数の急増やブロックされた外部ドメインを中心に点検します。
この項目を含む127項目を、URLを入れるだけで無料診断します。