Web

CORPヘッダーを使って、自分のサイトの画像を他のサイトから直リンクさせない方法

投稿日:2021年6月7日 更新日:

1. 画像ファイルが直リンクされる問題

例えば本Webサイトには、以下のURLで公開されている画像ファイルが配置されています。

このURLを、HTMLタグの1つである <img> タグの src 属性に指定することで、Webページ上にこの画像を表示することができます。

<img src="https://laboradian.com/wp-content/uploads/2018/07/web.min_.png"
     width="680" height="357" alt="Web">

この画像ファイルは、laboradian.com ドメインのWebページ上だけでなく、他のドメインの Webページから参照することが(通常は)できるので、見ず知らずの Webページに上記の <img> タグが記述されれば、この画像を表示することができてしまいます。

これは「直リンク」と呼ばれ、迷惑な行為であるとされています。勝手に画像が使われるだけでなく、こちらの運営しているWebサーバーから画像が取得されるため、サーバーのCPU負担・転送量の増加につながり利用料金まで増えてしまう可能性があります。

2. 他のサイトから、こちらの画像を参照できないようにする

2-1. Cross-Origin-Resource-Policy ヘッダーを返す

これを防ぐ方法ですが、画像ファイルに対するアクセスに対して、以下のHTTPレスポンスヘッダを返します。

Cross-Origin-Resource-Policy: same-site

もう少し制限を厳しくする場合は、以下を返します。

Cross-Origin-Resource-Policy: same-origin

2-2. Cross-Origin-Resource-Policy に指定できる値

Cross-Origin-Resource-Policy には以下の3種類の値を指定することができます。

Cross-Origin-Resource-Policy に指定できる値
意味
same-origin 同じオリジン (same-origin)[1] からのリクエストのみが、このリソースを読み取ることができる。
same-site 同じサイト (same-site)[2] からのリクエストのみが、このリソースを読み取ることができる。
cross-origin どのサイトからでも、このリソースを読み取ることができる。

[1]「同じオリジン」とは、今アクセスしているサイトのURLとそのページ上から表示しようとしている画像ファイルのURLを比べたときに、「http(s) の部分が同じ」且つ「ホスト部分が同じ」且つ「ポート番号が同じ」である場合を指します。

[2]「同じサイト」とは、URL上の「registrable domain が同じ」という意味になります(「eTLD+1 が同じ」と言ったほうが正確ですが説明が少し大変なので省略します)。registrable domain というのは「登録できるドメイン」という意味で、例えば「example.com」は該当しますが、「com」は該当しません。レジストラ(ドメイン登録業者)で取得できるドメインのことです。

same origin や same site については、7.5 Origin | HTML StandardUnderstanding “same-site” and “same-origin” に詳細な説明が載っています。後者のリンク先では、eTLD+1 についても説明されています。

2-3. .htaccess ファイルに書く場合

.htaccess ファイルが使えるサーバーであれば、.htaccess ファイルに以下のように記述することで、先のヘッダーを返すことができます。

<FilesMatch "\.(webp|jfif|jpg|jpeg|png|gif|ico)$"> 
  <IfModule mod_headers.c>
    Header set Cross-Origin-Resource-Policy "same-site"
  </IfModule>
</FilesMatch>

もしくは、画像が入ったディレクトリのトップ階層の .htaccess ファイルに以下を記述してもよいです。

<IfModule mod_headers.c>
  Header set Cross-Origin-Resource-Policy "same-site"
</IfModule>

3. スクリーンショット

Chrome ブラウザのデベロッパー ツールに表示される内容をいくつか示します。

3-1. 同じサイト (same site) で画像を表示した場合

画像ファイルと同じサイト上であれば、問題なく画像が表示されます。

以下のように、HTTP Response Headers に「cross-origin-resource-policy: same site」と出力されていますが、問題はないので「Status Code: 200(正常)」が返ってきています。

画像と同じサイト(正確には same site)で画像を表示した場合

3-2. 別のサイト (same siteではない) で画像を表示した場合

same site ではないサイト上で、先程の画像を表示しようとするとエラーが発生して表示できません。

以下のように、[Console] パネルにエラーが表示されています。「画像を読み込む処理がブロックされた」というエラーです。

[Console] パネルにエラーが表示される

画像ファイルから返ってきたレスポンスヘッダに「cross-origin-resource-policy: same site」が出力されており、エラーの内容も表示されています。

HTTP レスポンスヘッダに警告文?が表示されます。

「異なるサイト」からこのリソースを読み込むために、「Cross-Origin-Resource-Policy: cross-origin」を出力して制限を緩めることができる(但し、この画像を読み込んだ任意のサイトがセキュリティ上のリスクをもたらさない場合のみ、そうしてください)と書いてあります。

その説明の下にある「Learn more in the issues tab」をクリックすると、以下のように [Issues] タブが開きます。

[Issues] タブにもエラーが表示されます。

こちらでも同じようなメッセージが表示されています。

※ メッセージの中に「Cross-Origin-Embebdder-Policy: cross-origin」とありますが、これは「Cross-Origin-Resource-Policy: cross-origin」の間違いだと思われます。ついでに言うと、その前にある「HTML response header」は「HTTP response header」が正しいです。

4. 参考

📂-Web

執筆者:labo


comment

メールアドレスが公開されることはありません。

関連記事

Glitch

Glitch に DokiWiki を設置しようとして失敗しました

Glitch に DokuWiki を設置しようとしたのですが、残念ながら失敗してしまいました。ここにその記録を残しておこうと思います。

WebAssembly を試してみた

2018年10月における WebAssembly の状況を記録するために、現時点での WebAssembly を試してみることにしました。 目次1. WebAssembly とは?WebAssembl …

Web Vitals

LCP を意識した Highlight.js の読み込み方

LCP を意識した Highlight.js の読み込み方について説明します。

web development

HTTPレスポンスヘッダ COEP, COOP, CORP, CORS についてのメモ

HTTP Response Header である COEP, COOP, CORP, CORS についてのメモです。

Let's Encrypt

Let’s Encrypt: ホスト名毎に証明書を分けて発行する

ホスト名毎に証明書を分けて発行すると便利です。