結論(Cross-Origin-Embedder-Policy)
Cross-Origin-Embedder-Policy(COEP)とは、ページが別オリジンの画像・スクリプト・iframeなどを no-cors モードで読み込むときに、相手側の明示的な許可を必要とするかを決めるレスポンスヘッダーです。require-corp または credentialless にし、COOP を same-origin にするとクロスオリジン分離状態になり、SharedArrayBuffer などが使えます。一般的な情報提供サイトで必須ではなく、不用意に require-corp を入れると外部の地図や動画が表示されなくなる点に注意が必要です。
この記事のポイント
- 値は unsafe-none(既定)・require-corp・credentialless の3つです。
- COEP(require-corp か credentialless)と COOP(same-origin)がそろうとクロスオリジン分離になります。
- require-corp を全体に入れると、CORPを返さない外部の画像・地図・動画・SNS埋め込みが読み込めなくなります。
- 分離が不要なサイトは設定せず△を許容し、必要なアプリのパスだけに Report-Only から導入するのが安全です。
- セキュリティAIチェッカーは有効値を○、未設定・unsafe-noneを△、不正値を×、HTTP応答を対象外(重み1)とします。
| 診断項目名 | Cross-Origin-Embedder-Policy |
|---|---|
| 項目ID | headers.coep |
| 分類 | セキュリティヘッダー |
| 重大度・配点の重み | 低(low) 重み 1 |
| 関連する標準・ガイドライン | HTML Standard(Embedder policies / cross-origin isolation)、WHATWG Fetch Standard(CORP チェックとの連携)、OWASP WSTG-CONF-14(COOP と COEP をクロスオリジン分離のためのヘッダーとして扱う)、OWASP Secure Headers Project(推奨値の例 require-corp)、CWE-693(Protection Mechanism Failure)。OWASP ASVS 5.0.0 には COEP の設定を直接求める要件はありません(COOP は V3.4.8、CORP は V3.5.8 で扱われます)。 |
Cross-Origin-Embedder-Policy(COEP)とは
**Cross-Origin-Embedder-Policy(COEP)**とは、ページが別オリジンのリソース(画像、スクリプト、iframe など)を no-cors モードで読み込むときに、相手側の明示的な許可を必要とするかどうかを決めるレスポンスヘッダーです。
Cross-Origin-Embedder-Policy: require-corp
COEP を require-corp または credentialless にし、さらに COOP を same-origin にすると、ページは「クロスオリジン分離(cross-origin isolated)」状態になります。この状態でのみ SharedArrayBuffer や高精度タイマーなど、Spectre 型の攻撃に悪用されやすい機能が使えるようになります。言い換えると、COEP は主に高度な機能を安全に使うための仕組みであり、一般的な情報提供サイトで必須のものではありません。
この診断では、COEP が正しい書式で有効な値になっているかを確認します。自治体サイトでは、外部の地図や動画を埋め込むことが多く、require-corp を不用意に設定するとそれらが表示されなくなるため、導入前の確認が特に重要です。
COEPの値と仕組み
3つの値と動作
| 値 | 動作 |
|---|---|
unsafe-none | 既定値。別オリジンの no-cors リソースを許可なしで読み込める |
require-corp | 別オリジンの no-cors リソースは、相手が Cross-Origin-Resource-Policy で許可しているか、CORS で読み込んだ場合だけ読み込める |
credentialless | 別オリジンの no-cors リソースを CORP なしで読み込めるが、Cookie などの資格情報を送らず、応答の Cookie も無視する |
HTML Standard では、require-corp と credentialless が「クロスオリジン分離と両立する」値とされています。
構文と、保護が無効になる書き方
COEP は Structured Fields のトークンとして解釈され、report-to パラメーターを付けられます。
Reporting-Endpoints: coep-endpoint="https://www.example.lg.jp/reports/coep"
Cross-Origin-Embedder-Policy: require-corp; report-to="coep-endpoint"
HTML Standard は、不明な値や、ヘッダーの重複でリストになった値は unsafe-none として扱う(fail open)と定めています。
- トークンは大文字小文字を区別するため、
Require-Corpのような表記も無効です。 - HTTP で配信されたページ(非セキュアコンテキスト)では COEP 自体が無視されます。
- ブロックせずに違反だけを報告する
Cross-Origin-Embedder-Policy-Report-Onlyもあります。
CORPとの関係(提供側と読み込み側)
OWASP Secure Headers Project の整理では、CORP は「リソースを提供する側」、COEP は「リソースを読み込む側」のヘッダーです。COEP の require-corp を設定したページで別オリジンの画像を表示するには、画像の配信元が Cross-Origin-Resource-Policy: cross-origin を返すか、<img crossorigin> で CORS により読み込み、配信元が CORS を許可している必要があります。提供側のヘッダーは「Cross-Origin-Resource-Policy」、分離のもう1つの条件は「Cross-Origin-Opener-Policy」の項目で確認します。
COEPについてよくある誤解
- 「COEP は付ければ付けるほど安全」:COEP 自体が攻撃を直接防ぐのではなく、クロスオリジン分離を実現する条件の1つです。分離された機能を使わないサイトにとって、セキュリティ上の追加効果は限定的です。
- 「
unsafe-noneと書けば対応済み」:既定値と同じで、何も変わりません。 - 「
credentiallessなら何も壊れない」:Cookie を送らないため、ログイン状態に依存する外部リソースは表示が変わります。また、iframe の扱いなどrequire-corpと同様の制約が残る部分があります。ブラウザの対応状況も MDN の互換性表で確認が必要です。
Cross-Origin-Embedder-Policyの診断基準(セキュリティAIチェッカー)
取得方法
- 入力URLへ GET を1回送り、リダイレクト(最大4回)後の最終応答の
Cross-Origin-Embedder-Policyヘッダーを評価します。追加の通信は行いません。 - 最終URLが HTTPS でない場合、ブラウザは COEP を無視するため、この項目は対象外とします。
- 値の前後の空白を除き、
;より前のトークンだけを取り出して、大文字小文字を区別して判定します。report-toパラメーターは判定に影響しません。 Cross-Origin-Embedder-Policy-Report-Onlyは評価対象外です。
判定条件
| 判定 | 条件 | 得点への影響 |
|---|---|---|
| ○ 問題なし(pass) | トークンが require-corp または credentialless | 重み1を満点加算 |
| △ 要確認(warn) | ヘッダーがない | 1×0.45=0.45点 |
| △ 要確認(warn) | トークンが unsafe-none(既定値と同じ) | 1×0.45=0.45点 |
| × 要改善(fail) | 上記以外(綴り誤り、大文字を含む表記、重複付与によるカンマ区切りなど)。ブラウザは unsafe-none として扱う | 0点 |
| 対象外(na) | 最終URLが HTTPS でない | 採点から除外 |
- △ は「クロスオリジン分離が有効になっていない」ことを示す要確認の印です。分離を必要としないサイトでは、埋め込みへの影響を考え、△ のまま運用することも合理的な判断です。重み1・重大度 low としているのはこのためです。
- × は、管理者が設定したつもりの値がブラウザに無視されている状態を示します。
- 根拠欄にはヘッダー値を表示し、
unsafe-noneの場合は既定値と同じでクロスオリジン分離が有効にならない旨を補足します。
自治体サイトでの判定例
| 応答ヘッダー | 判定 | 補足 |
|---|---|---|
| ヘッダーなし(YouTube・地図を埋め込む一般的な公式サイト) | △ | 分離が不要なら許容できる |
unsafe-none | △ | 既定値と同じ |
credentialless | ○ | 埋め込みの動作確認が前提 |
require-corp; report-to="coep" | ○ | パラメーター付きでも有効 |
require-corp, require-corp(二重付与) | × | 解析に失敗し無効 |
require_corp(綴り誤り) | × | 無効 |
Require-Corp(大文字を含む) | × | トークンは大文字小文字を区別する |
最終URLが http:// | 対象外 | ブラウザが COEP を無視する |
COEPがない場合・誤って導入した場合のリスク
COEPがない場合のリスク
COEP がないこと自体で直接悪用される脆弱性は通常ありません。関係するのは次のような場面です。
- Spectre 型サイドチャネル:2018年に公表された Spectre 系の脆弱性では、同じプロセス内のメモリを推測される可能性が示されました。ブラウザは、高精度タイマーや
SharedArrayBufferを、クロスオリジン分離されたページに限って提供することで対策しています。分離を前提とした機能を使うアプリ(ブラウザ内での動画・音声処理、WebAssembly のマルチスレッドなど)で COEP がないと、その機能自体が使えません。 - 意図しない資格情報付きの読み込み:
credentiallessを使うと、別オリジンのno-corsリソースへ Cookie を送らなくなるため、資格情報付きで読み込んだ内容が分離されていない環境に置かれる状況を減らせます。
COEPを誤って導入した場合のリスク(可用性)
自治体サイトで実際に問題になりやすいのはこちらです。
require-corpを設定すると、CORP を返さない外部の画像、地図タイル、動画プレーヤー、SNS 埋め込み、アクセス解析のビーコン画像などが読み込めなくなります。- 災害情報や避難所マップなどが表示されなくなると、住民の安全に関わる情報提供に支障が出ます。
このため、COEP は「設定していないこと」よりも「確認せずに強い値を設定すること」の方が影響が大きい項目です。
COEPの設定方法(Apache・nginx・IIS・Next.js)
導入するかどうかの判断の流れ
- クロスオリジン分離が必要か確認する:
SharedArrayBufferやマルチスレッドの WebAssembly などを使うアプリがあるか、開発者・ベンダーに確認します。一般的な CMS で作られた公式サイトでは、通常は不要です。 - 不要な場合:COEP は設定せず、この項目の △ を許容します。COOP(
same-origin)や CSP、Permissions-Policy など、効果の大きい他の対策を優先します。 - 必要な場合:そのアプリのパスに限定して、まず Report-Only で影響を調べ、問題がないことを確認してから本適用します。
Report-Onlyでの段階的導入
<IfModule mod_headers.c>
Header always set Reporting-Endpoints "coep=\"https://www.example.lg.jp/reports/coep\""
Header always set Cross-Origin-Embedder-Policy-Report-Only "require-corp; report-to=\"coep\""
</IfModule>
報告された違反リソース(外部画像、埋め込みなど)について、配信元に CORP の付与を依頼する、crossorigin 属性で CORS 読み込みに切り替える、または credentialless を検討します。
Apache(特定ディレクトリだけに適用する例)
# /app/wasm-tool/.htaccess
<IfModule mod_headers.c>
Header always set Cross-Origin-Opener-Policy "same-origin"
Header always set Cross-Origin-Embedder-Policy "require-corp"
</IfModule>
nginx
location /app/wasm-tool/ {
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
}
IIS(web.config の location 指定)
<location path="app/wasm-tool">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cross-Origin-Embedder-Policy" value="require-corp" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
Next.js(Vercel)
// next.config.js:特定パスだけに適用
module.exports = {
async headers() {
return [{
source: "/tools/:path*",
headers: [
{ key: "Cross-Origin-Opener-Policy", value: "same-origin" },
{ key: "Cross-Origin-Embedder-Policy", value: "credentialless" },
],
}];
},
};
サイトを壊さないための注意点
- サイト全体(ルートの
.htaccessや共通設定)にrequire-corpを入れないでください。配下のすべてのページで外部埋め込みが止まる可能性があります。 - 導入後は、地図、動画、SNS 埋め込み、外部フォーム、アクセス解析が動いているか、実際のページで確認します。
- ヘッダーの付与箇所は1か所にし、二重付与による無効化を防ぎます。
設定後の確認方法
curl -sI https://www.example.lg.jp/app/wasm-tool/ | grep -i -E "cross-origin-(embedder|opener)-policy"
ブラウザの開発者ツールのコンソールで self.crossOriginIsolated を実行し、true になればクロスオリジン分離が有効です。セキュリティAIチェッカーは入力URLの応答を評価するため、特定パスだけに適用した場合は、そのパスのURLを入力して再診断します。
よくある質問(FAQ)
COEPは自治体サイトに必須ですか?
必須ではありません。COEPは主にSharedArrayBufferやマルチスレッドのWebAssemblyなど、クロスオリジン分離を前提とする機能を安全に使うための仕組みです。一般的なCMSで作られた公式サイトでは通常不要で、診断の△を許容する運用も合理的です。
require-corpを設定したら地図や動画が表示されなくなりました。なぜですか?
require-corpでは、別オリジンのno-corsリソースは、配信元がCross-Origin-Resource-Policyで許可しているか、CORSで読み込んだ場合しか読み込めません。CORPを返さない外部の画像、地図タイル、動画プレーヤー、SNS埋め込みなどはブロックされます。
require-corpとcredentiallessの違いは何ですか?
require-corpは別オリジンのno-corsリソースにCORPまたはCORSによる許可を求めます。credentiallessはCORPなしでも読み込めますが、Cookieなどの資格情報を送らず、応答のCookieも無視します。どちらもクロスオリジン分離と両立する値です。
credentiallessなら何も壊れませんか?
壊れないとは限りません。Cookieを送らないため、ログイン状態に依存する外部リソースは表示が変わります。iframeの扱いなどrequire-corpと同様の制約が残る部分もあり、ブラウザの対応状況もMDNの互換性表で確認が必要です。
クロスオリジン分離が有効になったかはどう確認しますか?
ブラウザの開発者ツールのコンソールで self.crossOriginIsolated を実行し、true になれば有効です。あわせてcurlでCOOPとCOEPのヘッダーが返っているかを確認します。
COEPが未設定だとセキュリティAIチェッカーでどう判定されますか?
「△ 要確認」(重み1の45%)で、unsafe-none の場合も同じです。△はクロスオリジン分離が有効でないことを示す印で、分離が不要なサイトではそのまま運用しても構いません。綴り誤りや二重付与などの不正値は×です。
この項目を含む127項目を、URLを入れるだけで無料診断します。