結論(Cross-Origin-Resource-Policy)
Cross-Origin-Resource-Policy(CORP)とは、リソースを提供する側が「自分のリソースを、どのオリジン・サイトのページから no-cors で読み込ませてよいか」を same-origin・same-site・cross-origin の3値で宣言するレスポンスヘッダーです。他サイトが img や script 要素で読み込もうとしたとき、許可されていなければブラウザは応答を渡しません。Spectre型サイドチャネルやXSSIで応答内容を読み取られるのを防ぎ、COEP(require-corp)のページから読み込まれるときの許可証にもなります。
この記事のポイント
- 値は same-origin(同一オリジンのみ)・same-site(同一サイト)・cross-origin(すべて)の3つです。
- CORPはno-corsリクエストにだけ作用し、CORSリクエストや同一オリジン、通常のページ遷移は制限しません。
- 未設定はcross-originと同じ扱いで、不正な値や二重付与は制限として働きません。
- ログイン後の画面やAPIはsame-origin、サブドメイン間共有はsame-site、公開素材はcross-originが目安です。
- セキュリティAIチェッカーは3値のいずれかを○、未設定を△、不正値を×(重み1)と判定します。
| 診断項目名 | Cross-Origin-Resource-Policy |
|---|---|
| 項目ID | headers.corp |
| 分類 | セキュリティヘッダー |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | OWASP ASVS 5.0.0 V3.5.8(認証が必要なリソースが、意図した場合にのみ読み込み・埋め込みされるようにする。Sec-Fetch-* の検証、または制限的な Cross-Origin-Resource-Policy で実現。Level 3)、WHATWG Fetch Standard(Cross-Origin-Resource-Policy header)、OWASP Secure Headers Project(推奨値の例 same-origin)、CWE-693(Protection Mechanism Failure。OWASP ZAP アラート 90004 の分類) |
Cross-Origin-Resource-Policy(CORP)とは
**Cross-Origin-Resource-Policy(CORP)**とは、リソースを提供する側が「自分のリソースを、どのオリジン・サイトのページから no-cors で読み込ませてよいか」を宣言するレスポンスヘッダーです。他サイトが <img> や <script> などで自サイトのリソースを読み込もうとしたとき、ブラウザが CORP を確認し、許可されていなければ応答を読み込ませません。
Cross-Origin-Resource-Policy: same-origin
主な目的は、Spectre 型のサイドチャネル攻撃や XSSI(クロスサイトスクリプトインクルージョン)で、他サイトのページから自サイトの応答内容を間接的に読み取られることを防ぐことです。また、COEP(require-corp)を設定したページが別オリジンのリソースを読み込むときの「許可証」としても使われます。読み込む側のヘッダーは「Cross-Origin-Embedder-Policy」で確認します。
自治体サイトでは、公開画像やPDFを他の自治体・報道機関・ポータルサイトが参照する場合もあるため、守りたいもの(ログイン後の画面、個人向けデータ)と公開して共有したいものを分けて値を選ぶことが大切です。
CORPの値と仕組み
3つの値と読み込みを許す範囲
| 値 | 読み込みを許すページ |
|---|---|
same-origin | 同一オリジン(スキーム・ホスト・ポートがすべて一致)のページのみ |
same-site | 同一サイト(例:www.example.lg.jp と bousai.example.lg.jp のように登録可能ドメインとスキームが同じ)のページ |
cross-origin | すべてのオリジン。COEP require-corp のページから読み込ませたい公開リソースに付ける |
CORPが作用する範囲
- MDN によれば、CORP は
no-corsリクエストにだけ作用し、CORS リクエストや同一オリジンのリクエストには影響しません。 - 通常のページ遷移(リンクをクリックしてページを開く)は制限しません。
- COEP
require-corpのページに iframe で埋め込まれる文書の扱いなど、ブラウザ実装によって細部が異なる場合があります。 - Fetch Standard では、値が3つのいずれにも一致しない場合、そのヘッダーは制限として働きません。同じヘッダーを2回付けて値がカンマで連結された場合も同様です。値は大文字小文字を区別する(case-sensitive)と定義されており、
Same-Originのような表記も一致しません。
CORPを付けない場合の扱い
OWASP Secure Headers Project は、CORP が指定されていない場合、ブラウザは cross-origin と同じように扱うと説明しています。つまり未設定は「どこからでも no-cors で読み込める」状態です。MDN HTTP Observatory は CORP の未設定を減点対象にしていませんが、OWASP ZAP は未設定または不正値をアラートとして報告します。
CORPについてよくある誤解
- 「CORP を付けると画像の直リンクを完全に防げる」:他サイトの
<img>表示は防げますが、URL を直接開く操作やサーバー間の取得は防げません。著作権保護やアクセス制御の代わりにはなりません。 - 「CORP は CORS の一種」:別の仕組みです。CORS はクロスオリジンで内容を読む許可(
Access-Control-Allow-Origin)、CORP はno-corsの埋め込み読み込みを制限する宣言です。CORS の設定は「危険なCORSワイルドカードがない」などの項目で確認します。 - 「HTML ページにだけ付ければよい」:効果が大きいのは、ログイン後の JSON、ユーザー固有の画像・ファイルなど、他サイトから読み込まれると困るリソースです。
Cross-Origin-Resource-Policyの診断基準(セキュリティAIチェッカー)
取得方法
- 入力URLへ GET を1回送り、リダイレクト(最大4回)後の最終応答の
Cross-Origin-Resource-Policyヘッダーを評価します。追加の通信は行いません。 - 値は前後の空白を除き、大文字小文字を区別した完全一致で判定します(Fetch Standard の定義と同じ)。
- 画像・PDF・API など、トップページ以外のリソースの CORP は、この項目では確認していません。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | 値が same-origin、same-site、cross-origin のいずれか | 重み1を満点加算 |
| △ 要確認(warn) | ヘッダーがない(ブラウザは制限なしとして扱う) | 1×0.45=0.45点 |
| × 要改善(fail) | 上記以外の値(綴り誤り、大文字を含む表記、二重付与によるカンマ連結、パラメーター付きなど)。ブラウザは制限として扱わない | 0点 |
| 対象外(na) | この項目では使いません | ― |
cross-originも ○ としています。公開サイトが「どこからでも読み込んでよい」と明示的に宣言するのは正当な選択であり、COEP を使う他サイトとの互換性のために必要な場合もあるためです。- 根拠欄にはヘッダー値、または「CORPがありません。」を表示します。
自治体サイトでの判定例
| 応答ヘッダー | 判定 |
|---|---|
same-origin | ○ |
same-site(本庁サイトと防災サイトをサブドメインで運用) | ○ |
cross-origin(オープンデータ配信サイト) | ○ |
| ヘッダーなし | △ |
same-origin, same-origin(二重付与) | × |
sameorigin(綴り誤り) | × |
Same-Origin(大文字を含む) | × |
CORPがないとどんなリスクがあるか
攻撃シナリオ
- Spectre 型サイドチャネルによる読み取り:攻撃者のページが、住民マイページの個人情報を返す URL を
<img>や<script>で読み込ませる。ブラウザは表示できなくても応答を同じプロセスのメモリに取り込む場合があり、サイドチャネル攻撃で内容を推測される可能性があります。CORPsame-originを付けると、ブラウザは応答を攻撃者のページに渡しません。 - XSSI(クロスサイトスクリプトインクルージョン):ログイン状態で JavaScript として解釈できる形式(JSONP や JS 変数代入)の個人データを返すエンドポイントを、攻撃者のページが
<script src>で読み込み、値を取得する。CORP と nosniff を組み合わせると防ぎやすくなります(nosniff は「MIMEスニッフィング対策」で確認します)。 - 他サイトでの無断埋め込み:職員向けの資料画像などを他サイトに埋め込まれ、内部情報が拡散する。CORP は他サイトでの表示を止めますが、URL を知っている人が直接開くことは防げないため、アクセス制御と併用が必要です。
想定される被害
- 住民のログイン後データ(申請状況、個人情報)の推測・漏えい
- 内部資料の意図しない拡散
公開情報だけのトップページでは影響が小さいため重大度は low ですが、ログイン機能やユーザー固有データを持つシステムでは ASVS V3.5.8 の観点から重要になります。
CORPの設定方法(Apache・nginx・IIS・Next.js)
値の選び方
| リソースの種類 | 推奨値 |
|---|---|
| ログイン後の画面・API、ユーザー固有のファイル | same-origin |
| 本庁・防災・観光などサブドメイン間で共有する画像・スクリプト | same-site |
| 他団体やポータルへの掲載を想定した公開画像・オープンデータ | cross-origin |
| 一般的な公開ページ(HTML) | same-origin または same-site |
Apache(.htaccess)
<IfModule mod_headers.c>
# サイト全体の既定値
Header always set Cross-Origin-Resource-Policy "same-site"
</IfModule>
# 公開素材ディレクトリ(/opendata/.htaccess)だけ外部からの読み込みを許可
<IfModule mod_headers.c>
Header always set Cross-Origin-Resource-Policy "cross-origin"
</IfModule>
nginx
add_header Cross-Origin-Resource-Policy "same-site" always;
location /opendata/ {
add_header Cross-Origin-Resource-Policy "cross-origin" always;
}
location /mypage/ {
add_header Cross-Origin-Resource-Policy "same-origin" always;
}
location 内に add_header を書くと、server レベルの add_header(他のセキュリティヘッダーを含む)は継承されません。各 location に必要なヘッダーをまとめて記述してください(nginx 1.29.3 以降は add_header_inherit merge; で上位の設定を引き継げます)。
IIS(web.config)
<httpProtocol>
<customHeaders>
<add name="Cross-Origin-Resource-Policy" value="same-site" />
</customHeaders>
</httpProtocol>
Next.js(Vercel)
// next.config.js
module.exports = {
async headers() {
return [
{ source: "/:path*", headers: [{ key: "Cross-Origin-Resource-Policy", value: "same-site" }] },
{ source: "/opendata/:path*", headers: [{ key: "Cross-Origin-Resource-Policy", value: "cross-origin" }] },
];
},
};
サイトを壊さないための注意点
- 外部掲載への影響:
same-originをサイト全体に付けると、他の自治体サイト、報道機関、地域ポータル、SNS のプレビューなどで画像が表示されなくなる可能性があります。共有を想定する画像・PDF のディレクトリはcross-originにするか、適用範囲から外します。 - サブドメイン構成:画像を
www以外のサブドメイン(img.example.lg.jpなど)から配信している場合、same-originでは本体ページで表示できなくなることがあります。same-siteを選びます。 - CDN 経由の配信:画像を外部 CDN の別ドメインから配信している場合、そのドメインは別サイト扱いになるため、CDN 側の応答に適切な CORP(多くは
cross-origin)が必要です。 - 二重付与の防止:付与箇所は1か所にします。値が連結されると無効になります。
設定後の確認方法
curl -sI https://www.example.lg.jp/ | grep -i cross-origin-resource-policy
curl -sI https://www.example.lg.jp/opendata/sample.csv | grep -i cross-origin-resource-policy
設定後は、他のドメインから画像を参照しているページ(関連団体のサイトなど)で表示が崩れていないか、ブラウザの開発者ツールのコンソールに ERR_BLOCKED_BY_RESPONSE.NotSameOrigin などのブロックが出ていないかを確認します。セキュリティAIチェッカーで再診断し、根拠欄に3値のいずれかが1つだけ表示されていることも確かめてください。
よくある質問(FAQ)
CORPとCORSの違いは何ですか?
別の仕組みです。CORSはクロスオリジンで内容を読む許可(Access-Control-Allow-Origin)を与えるもので、CORPは img や script などの no-cors の埋め込み読み込みを制限する宣言です。CORPはCORSリクエストには影響しません。
CORPのsame-originとsame-siteの違いは何ですか?
same-originはスキーム・ホスト・ポートがすべて一致するページだけに読み込みを許します。same-siteは、www.example.lg.jp と bousai.example.lg.jp のように登録可能ドメインとスキームが同じページにも許します。
CORPのcross-originを設定しても意味はありますか?
あります。公開サイトが「どこからでも読み込んでよい」と明示的に宣言するのは正当な選択で、COEPを使う他サイトとの互換性のために必要な場合もあります。セキュリティAIチェッカーでもcross-originは○です。
CORPを付ければ画像の直リンクを完全に防げますか?
防げません。他サイトの img 要素での表示は止められますが、URLを直接開く操作やサーバー間の取得は防げません。著作権保護やアクセス制御の代わりにはならないため、アクセス制御と併用します。
サイト全体にsame-originを付けても大丈夫ですか?
他の自治体サイト、報道機関、地域ポータル、SNSのプレビューなどで画像が表示されなくなる可能性があります。共有を想定する画像・PDFのディレクトリはcross-originにするか、適用範囲から外してください。
CORPの値をSame-Originと書いたらどう判定されますか?
値は大文字小文字を区別する完全一致で判定されるため、Same-Originは無効で「× 要改善」です。綴り誤り、二重付与によるカンマ連結、パラメーター付きの値も×になります。
この項目を含む127項目を、URLを入れるだけで無料診断します。
参考資料
- WHATWG Fetch Standard(Cross-Origin-Resource-Policy header)
- MDN: Cross-Origin-Resource-Policy
- OWASP ASVS 5.0.0 V3 Web Frontend Security(V3.5.8)
- OWASP Secure Headers Project(CORP の値と CORP/COEP の関係)
- MDN HTTP Observatory の CORP テスト実装
- OWASP ZAP Alert 90004(Cross-Origin-Resource-Policy Header Missing or Invalid)