主要ブラウザのReferrer Policyについて調べてみた

# はじめに
私は最近Referrer Policyというものを知りました。
これを知っていると、「自分のブラウザは自分の行動をどの程度アクセス先にバラしてるのか？」の一部を知ることができます。
Referrer Policyを理解するために、まずは**Referer**(リファラ)という言葉について知る必要があります。  
(ちなみに仕様書読めば理解できるって人は W3C Candidate Recommendation を読むとここより詳しく分かるらしいです)
[Referrer Policy W3C Candidate Recommendation, 26 January 2017][1]

# 私がこれを知って調べた動機
(Referrer Policyの理解には必要ないので読み飛ばしても大丈夫です)
　大学のセキュリティに関する講義で、講義が指定したあるサイトでGETメソッドでデータを送ったあと、そこに載ってるリンクから自分のサーバー上のウェブサイトへ飛び、ログを見てみましょうという課題がありました。
　私はそこで、「きっとRefererにはGETメソッドで送信したパラメータが残ってるんだろうな」と思い、またその課題もその危険性を知ってもらうためのものなんだろうな、とも思いました。
しかし実際にChromeでアクセスし、ログを取ってみたところ、Refererにはドメイン名までしか記載されていませんでした。これに疑問を持ったのが私がReferrer Policyを調べた動機です。

# Refererとは
Refererとは、HTTPリクエストヘッダの一つです。
あなたが、私のブログのQiitaのリンクをクリックしたとしましょう。
すると、あなたのブラウザは、Qiitaのページを読むためにリクエストをQiitaに対して飛ばします。
そのリクエストの中にあるリクエストヘッダの一つである**Referer**に、リンク元のURLが入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/a79cb87c-8787-d22a-8500-67e81a66c5a3.png)

つまり、Qiitaさんはアクセスログを見れば、「なるほど、このアクセスはこのURLから飛んできたのか」と知ることが出来ます。
サイトを運営している人は、この情報を「どのサイトからのアクセスが多いのか」といったアクセス解析に使ったことがあるかもしれません。

人によってはRefererにプライバシー的な懸念を抱くと思います。Refererの送出の有無の切り替えをする機能を備えたブラウザは以前からありましたが、最近ではReferrer Policyというものが実装されつつあります。

# Referrer Policyとは
Referrer Policyとは、リファラを扱う際のポリシーのことで、どの程度のリファラ情報を載せるかを決定しています。
これはW3C(WWWの標準化団体)によってW3C勧告候補になっています。
[Referrer Policy W3C Candidate Recommendation, 26 January 2017][1]
まだW3C勧告ではありませんが、既に対応しているブラウザもあります。

Referrer Policyにはいくつかのポリシーがあります。どんな種類のポリシーがあるのか見てみましょう。
## no-referrer-when-downgrade
このポリシーを設定すると、HTTPSのサイトからHTTPのサイトにアクセスするときに、Refererが送信されません。
例を挙げると、
**https**://example.com/page から **https**://mozzila.org にアクセスするとき、リクエストヘッダのRefererは https\://example.com/page になります。
しかし、**https**://example.com/page から **http**://example.org にアクセスするときは、Refererは送信されません。
これを分かりやすく表にしてみます。  

| ポリシー                  | アクセス元                   | アクセス先              | Referer                  |
| ------------------------- | ---------------------------- | ----------------------- | ------------------------ |
| no-referer-when-downgrade | **https**://example.com/page | **https**://mozzila.org | https\://example.com/page |
| 〃                        | **https**://example.com/page | **http**://example.org  | (リファラーなし)                   |

要は、「HTTPSからHTTPのサイトにアクセスするときはリファラーを添付しない」と定めているポリシーなのです。
  
なぜこのようなポリシーがあるのでしょうか？w3.orgによるとこう書いてあります。
> The "no-referrer-when-downgrade" policy sends a full URL along with requests from a TLS-protected environment settings object to a potentially trustworthy URL, and requests from clients which are not TLS-protected to any origin.  
> Requests from TLS-protected clients to non- potentially trustworthy URLs, on the other hand, will contain no referrer information. A Referer HTTP header will not be sent.

参照：[Referrer Policy W3C Candidate Recommendation, 26 January 2017][1]

HTTPから始まるURLは、潜在的に信頼できないURL (non-potentially trustworthy URLs) と書かれています。HTTPSから始まるURLのサイトは、SSL/TLSによって通信相手の認証や通信の暗号化がされますが、HTTPはされません。このことから潜在的に信頼できないURLだと書かれているのだと思います。

また、このポリシーはデフォルトのポリシーとして設定されています。（この意味に関しては後述します）
## strict-origin-when-cross-origin
これはユーザーにとって良いオプションです。先に表を載せます。

| ポリシー                        | アクセス元                   | アクセス先                       | Referer                  |
| ------------------------------- | ---------------------------- | -------------------------------- | ------------------------ |
| strict-origin-when-cross-origin | **https\://example.com**/page | **http\://example.com**/otherpage | https\://example.com/page |
| 〃                              | **https**://example.com/page | **https**://mozzila.org          | https\://example.com      |
| 〃                              | **https**://example.com/page | **http**://example.org           | (リファラーなし)         |

この表の各行はそれぞれ以下のようなことを言っています。

* オリジン（スキームとホストとポート番号の組み合わせ）が同じなら、完全なURLをRefererとして送ります。
* 同じスキーム（HTTPS）を使っていても、ホストが違うなら、Refererにはドメインしか添付しません。
* スキームが違う場合はリファラーを生成しません。

つまり、no-referrer-when-downgradeと比べると、HTTPSからHTTPにプロトコルがダウングレードする場合に限らず、ホストがそもそも違えば完全なURLをRefererとして送らない、という点が違いますね。プロトコルがダウングレードする際はリファラーを送らないという点は一緒です。

# ブラウザのデフォルト設定について
Referrer Policyにはほかにもいくつかのポリシーがありますが、今回は二つのみ紹介しました。
なぜかというと、その二つはブラウザのデフォルトとしてよく設定されているポリシーだからです。

Referrer PolicyはHTMLでも指定できます。例えばhead要素の中に  

```html
<meta name="referrer" content="no-referrer-when-downgrade">
```

と書いたとしましょう。
すると、そのページからのページ遷移のためのリクエストには、すべてcontent属性の値のReferrer Policyに従ってReferrerが付与されます。  

Q. ではHTMLやHTTPヘッダで指定されていない場合は？
A. デフォルトのReferrer Policy、つまり「no-referrer-when-downgrade」が使用されます。

しかし、ブラウザによっては独自にデフォルトのReferrer Policyを定めていたり、ユーザによって変更可能なものがあります。
さっそく各ブラウザのデフォルトのReferrer Policyを見る前に、そもそも各ブラウザがReferrer Policyを実装しているのか見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/c7097ad5-8425-8eec-4a40-4cd3006f3ac7.png)
転載元：https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy:title
パソコンではIE以外、スマホではSafari以外の主要なブラウザが実装しているようですね。
では、各ブラウザのデフォルト設定を見てみましょう。
## 各ブラウザのデフォルトReferrer Policy

### Firefox
Firefoxでは、デフォルトのReferrer Policyは以下の手順で確認できます。
1. アドレスバーに「about:config」と入力してエンターを押してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/40b65d83-d5bf-2060-0e48-5dd9dd9184c4.png)
2. 「危険性を承知の上で使用する」を押してください  
3. 表示されたページのテキストボックスに、「network.http.referer.defaultPolicy」と入力してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/23b2ecdf-29de-7c68-070b-0e933d80a7ae.png)

いくつか項目が出てきますが、「network.http.referer.defaultPolicy」の横の数字に注目してください。
この値がデフォルトのReferrer Policyを示しています。値の対応表を以下に示します。

| 値   | Referrer Policy                 |
| ---- | ------------------------------- |
| 0    | no-referrer                     |
| 1    | same-origin                     |
| 2    | strict-origin-when-cross-origin |
| 3    | no-referrer-when-downgrade      |
参考：https://wiki.mozilla.org/Security/Referrer

上に示した画像では値が「３」だったので、**no-referrer-when-downgrade** がFirefoxのデフォルトのReferrer Policy だと分かりました。
ちなみに、.pbmodeがついている項目の値は、プライベートブラウジング時のReferrer Policyを示しているようです。

### Google Chrome
Chromeはバージョン85から、デフォルトのReferrer Policyを「**strict-origin-when-cross-origin**」に設定したそうです。

参考：https://developers.google.com/web/updates/2020/07/referrer-policy-new-chrome-default#:~:text=referrer%20.,-Up%20until%20recently&text=Chrome%20plans%20to%20switch%20its,%2Dcross%2Dorigin%20by%20default

### Edge
Edgeはv86から、デフォルトのReferrer Policyを「**strict-origin-when-cross-origin**」に設定しました。
> This change is happening in the Chromium project, on which Microsoft Edge is based.  

とマイクロソフトのサイトに書かれている通り、EdgeのベースとなっているChrominiumプロジェクトによる変更だそうです。

参考：https://docs.microsoft.com/en-us/microsoft-edge/web-platform/site-impacting-changes　　

## 考察
各ブラウザのデフォルトReferrer Policyを見てみると、**Chrome**と**Edge**を使っている人は、Refererから情報が漏れることに関して、あまり心配する必要はないかもしれません。
一方W3Cでデフォルトに指定されている**no-referrer-when-downgrade**を使用している**Firefox**は、もし懸念があるのであれば、自分で設定を変えてもよいと思います。

IEはReferrer Policyに対応していないそうなので、ぜひ実装してほしいですね。

# まとめ
いかがでしたでしょうか。Referrer Policyについて何となく理解できたでしょうか。
他にもReferrer Policyはあるので、ぜひ調べてみてください。
このReferrer Policyについて調べる中で初めてW3Cやリファラの詳細について知ったので、もし至らない点があれば指摘してくださると幸いです。


# おまけ
## Q. どうやって動いているかイメージがわかない
A. 各ブラウザの開発者ツールの「Network」タブを見ながらインターネットサーフィンをしてみましょう。
各通信のリクエストヘッダを見ると referer が、Generalの欄を見ると使っている Referrer Policy が分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/554550c8-cdf1-3645-2433-0f5cc3d20292.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263988/21bc58c8-f797-730b-0ac7-3787e71d3b6e.png)


[1]:https://www.w3.org/TR/referrer-policy/