(new photo / Shutterstock.com)
こんにちは、中山です(写真は … 適当なものがありませんでした)。
世の中の Web サイトの HTTPS 化が フィッシングサイトも含めて(笑) 進んでいます。
一方で RFC には以下のように定められ、HTTP Referer を利用するサービスでは HTTPS 化に伴う影響が発生します。
5.5.2. Referer
A user agent MUST NOT send a Referer header field in an unsecured HTTP request if the referring page was received with a secure protocol.
さらに Referrer-Policy も考慮しつつ、今回は HTTPS と Referrer-Policy と HTTP Referer の関係性を検証してみます。
通常のページ遷移の場合
まずは下図のような通常のページ遷移について。
Referrer-Policy には
- no-referrer
- no-referrer-when-downgrade
- origin
- origin-when-cross-origin
- same-origin
- strict-origin
- strict-origin-when-cross-origin
- unsafe-url
と、細かな指定が可能ですが、今回は HTTP Referer が送信されるか否かをシンプルに検証するため
- Referrer-Policy 無し
- unsafe-url(常に HTTP Referer を送信する指示)
- no-referrer(常に HTTP Referer を送信しない指示)
の条件でクエリ ② の HTTP Referer を確認してみます。
結果は以下の通りでした。
Chrome(64.0.3282.140)と Firefox(58.0.2)ともに Referrer-Policy があればそれに従い、ない場合は RFC 通りの動作となりました。
リダイレクタを経由したページ遷移の場合
次いで下図のようなリダイレクタを経由したページ遷移について。
先程の条件を掛け合わせ、クエリ ④ の HTTP Referer を確認してみます。
結果は以下の通りでした。
(機械的に条件を掛け合わせたため、マトリクスが巨大ですがご容赦ください ^^;)
ご覧の通り Chrome と Firefox で幾つか異なる結果となりました。
この結果から
- Chrome はリダイレクタの Referrer-Policy に従う
※ ページAの Referrer-Policy が no-referrer の場合、リダイレクタに HTTP Referer が送信されないため、結果としてページBにも HTTP Referer は送信されません(リダイレクタの unsafe-url を無視しているわけではない) - Firefox はリダイレクタの Referrer-Policy を無視する
という実装が見て取れます。
では Referrer-Policy + リダイレクト に関する仕様を確認してみます。
8.2. Set request’s referrer policy on redirect
Given a request request and a response actualResponse, this algorithm updates request’s associated referrer policy according to the Referrer-Policy header (if any) in actualResponse.1. Let policy be the result of executing §8.1 Parse a referrer policy from a Referrer-Policy header on actualResponse.
2. If policy is not the empty string, then set request’s associated referrer policy to policy.
つまり、リダイレクタの Referrer-Policy に従う Chrome の動作が仕様通りということになります。
マーケティング関連サービスで、遷移先で HTTP Referer を参照させたい(ex. 流入計測)場合には
- リダイレクタを HTTPS 化
- リダイレクタの Referrer-Policy に unsafe-url を指定
することで、遷移元ページの HTTPS 化の影響を小さくすることが出来そうです。
他方、秘密にしたい情報が URL に含まれる場合には、遷移元で Referrer-Policy に no-referrer を指定するか META 要素もしくは A 要素で HTTP Referer 非送信の属性を指定をすべきですね。そうすることで HTTPS / HTTP によらずリダイレクタに HTTP Referer は送信されませんので。
おまけ
ページ遷移の方法に細工(例えば window.open() を利用する等)を用いることで HTTP Referer の有無が変化しますが、機会があればそちらの実験結果もご紹介したいと思います。