CNAMEトラッキングってなあに？

先日、というにはだいぶ前ですが、Chromeが[サードパーティCookieを禁止する](https://blog.chromium.org/2020/01/building-more-private-web-path-towards.html)と発表しました。

そこらへんを見ていたところCNAMEトラッキングとかいう楽しいワードを発見したので、自分の理解のためにまとめたものです。
従って正確性を欠いている部分が多々あります。
正しい解説は既に色々別なところが出しているので、そこらへんを見た方がいいと思います。


# Cookieの概要

CookieはFQDN単位で発行されます。
たとえば`qiita.com`で発行したCookieは、次回以降`qiita.com`にアクセスした場合に自動的に送信されます。
`blog.qiita.com`や`teams.qiita.com`にアクセスした場合は、本来は送信されません。

サブドメインが異なるだけでも別サイトと判定されるので、たとえば[ニコニコ動画](https://www.nicovideo.jp/)にログインしてから[ニコニコ生放送](https://live.nicovideo.jp/)に行ってもニコニコ生放送ではログアウト状態になってしまいます。
これでは使い勝手が悪すぎるので、[Domain属性](https://www.ietf.org/rfc/rfc6265.txt)を使ってCookieを送信する範囲を指定することが可能です。

QiitaのCookieは`domain=.qiita.com;`という指定がされていますが、これを指定すると`*.qiita.com`の全てのドメインに同じCookieが送られるようになります。
これによって、`zine.qiita.com`や`jobs.qiita.com`などのサブドメインに進んでも同じCookieが送信されるようになるため、ログイン状態を継続することができるようになります。

この指定はサブドメインより上には行けません。
すなわち、`domain=.com;`と書いてあらゆる`.com`にCookieを送信するとか、`*.ebis.ne.jp`とか書いて全然関係ないサイトにCookieを送信するといったことはできない、ということです。
安全性を考えると当然ですね。


# サードパーティCookieとは

ざっくり言うと、サイトAのCookieを別のサイトBから読み書きできる、というものです。
こんなものトラッキング以外の何に使えというのですかね。

```html:サイトAのindex.html
	<script src="サイトB/tracker.js"></script>
```

```html:サイトBのtracker.js
	document.cookie = xxx;
```

`tracker.js`が発行したCookieは、サイトAのものになります。

主体となるサイトAが、能動的にサイトBのJSを読み込む必要があります。
従ってサイトAが何らかの目的でJSを仕込むという使用法が主な使い方であり、サイトBが無差別に他所のCookieを読むようなことはできません。

これを何に使うかというと、まずはアクセス分析ですね。
CookieからセッションIDを取り出せば、誰がどのページをいつ見ていたかといった内容が集計できます。
そのようなものを個々のサイトでいちいち構築・管理するのは大変なので、Googleアナリティクスのような分析サービスが登場しました。
サードパーティCookieを使えばscriptタグをひとつ置くだけで簡単に集計できるので、多くのサイトが使用しています。

もちろんアクセス分析だけではなく、広告にも使われています。
どのようなページを多く見ているかを調査し、その人の性癖に最適な広告を表示するわけです。


# サードパーティCookieの対応状況

Firefoxは[デフォルトで禁止すると明言](https://support.mozilla.org/ja/kb/disable-third-party-cookies)しています。
SafariもEdgeも、意外なところでは旧IEも、サードパーティCookieは2010年代前半あたりまでにデフォルト禁止になっていました。
最近までデフォルト許可のまま残っていたのはChromeだけだったということです。

2020年にようやくChromeがデフォルト禁止への変更を発表したことで、ついにサードパーティCookieが滅びます。
めでたしめでたし。


# サードパーティCookieの歴史

2011年あたりまでの歴史は[サードパーティCookieの歴史と現状](https://mala.hatenadiary.org/entry/20111125/1322210819)を読めば解決。
当時の結論は[デフォルトブロックは無理、DNT使え](https://mala.hatenadiary.org/entry/20111130/1322668652)という風潮だったようですが、DNTなんて筋の悪い方法が有効に機能するわけもなく、ほとんどのブラウザはその後デフォルトブロックに舵を切りました。


# ファーストパーティCookieとは

同じドメイン、もしくはサブドメインのCookieです。

```html:サイトAのindex.html
	<script src="サイトAのサブドメイン/tracker.js"></script>
```

```html:サイトAのサブドメインのtracker.js
	document.cookie = xxx;
```

要するに普通のCookieです。
Domain属性を適切に設定すれば、サブドメインにもCookieが飛ぶのは上に書いたとおりです。

この仕組みを悪用したものがCNAMEトラッキングです。


# CNAMEトラッキングとは

DNSレコードを以下のように設定します。

```
www IN A 192.168.0.1
ac IN CNAME tracker.ebis.ne.jp.
```

どうなるかというと、`www.example.com`へのリクエストは`192.168.0.1`に飛びますが、`ac.example.com`へのリクエストは`tracker.ebis.ne.jp`に飛ぶようになります。
見た目は`ac.example.com`であり、`example.com`のサブドメインになっているのでCookieも飛びます。

見事にサードパーティCookieの制限を突破して、別のサーバでCookieを受け取ることができるようになりました。
サブドメインなので、サードパーティCookieのようにユーザ側で止める方法もありません。
いやあ斬新な回避策もあったものです。

問題点のひとつとしては、自社の管理するドメイン名の一部を他社に明け渡すことになるので、もしそちらで不祥事が起きたらこっちのせいになるということでしょうか。
いや違うんだ、`ac.example.com`で起きたんじゃないんだ、`tracker.ebis.ne.jp`が起こしたんだ、とか言ってもわかりませんしね。

# CNAMEトラッキングへの対策

CNAMEトラッキングについて、ユーザ側ではわりとどうしようもありません。
しかし一部のブラウザはこれも止めてしまうことを考えているようです。

# Intelligent Tracking Prevention

[Intelligent Tracking Prevention](https://webkit.org/blog/9661/preventing-tracking-prevention-tracking/)、通称ITPは、Safariが実装しているトラッキング対策です。
元々はサードパーティCookie向けの機能だったようですが、最近は機能が拡張しています。
`https://example.com/foo/bar/baz`から別サイトに飛ぶとリファラを`https://example.com/`に切り詰めたり、怪しいサイトからローカルストレージへのアクセスを禁止したりといった機能があるようです。

そして最近では、別のドメインなのにひとつのIPアドレスであればトラッキングと判断してNGする機能が追加されました。
CNAMEトラッキングを殺しにきた仕様ですね。

とにかくトラッキングは皆殺しだ、という発想です。
まあAppleなら、わざわざブラウザ経由で情報を抜かなくてもiPhone自体から抜き放題ですからね。
無関係な他社にまで情報を渡す必要は全くありません。


# プライバシーサンドボックス

ハードウェアを売れるAppleと違って、Googleは広告が打てなくなると死ぬので広告規制には慎重です。
最近の潮流には逆らえず規制を強化しようとはしていますが、その方向性は[プライバシーを侵害せずに広告を打てる](https://www.itmedia.co.jp/news/articles/1908/23/news056.html)というものです。

まあ、いちユーザの感想としては『絶滅させろ』なんですけどね。


# 今後はどうなる？

今後も様々な手段によってトラッキングがなされ、トラッキングがブロックされ、が繰り返されていくことでしょう。
CNAMEトラッキングも寿命はさほど長くなさそうです。

しかしひとつだけ、絶対にブロックされないトラッキングがあります。
すなわち、メインコンテンツと全く同じドメインで全く同じIPアドレスであればよいということです。

ということで、次世代のトラッキングはこれだ！

・サーバにはプログラムファイルをひとつ置くだけ。言語はサーバサイド言語であればなんでもいい。
・中身はトラッキングサーバからJavaScriptを取ってきて出力するだけ。
・クライアントからは`script`タグでそれを読み込む。

```php:PHPのサンプル
	header('Content-Type: application/javascript; charset=utf-8');
	echo file_get_contents( sprintf('https://tracking.example.com/?phpsessid=%s&referer=%s', session_id(), $_SERVER['HTTP_REFERER']) );
```

このJavaScriptは同じドメインにあるので、サードパーティCookieやらサブドメインやらの制限で止めることはできません。
なにしろ見た目は完全に正規のリクエストですからね、さすがにこれをブラウザが勝手に止めてしまうと大問題でしょう。

うむ、なんか大昔に見たことがあるようなシステムだな。

ともかくこれで止めようのないトラッキングが完成しました。
HTMLに`script`タグを埋め込むだけ、というお手軽さからは少しだけ遠のいてしまいましたが、それでも手間が少し増えるだけです。
めでたしめでたし(めでたくない)

まあそれでも、素人の私には思いつかない方法で止めてくるかもしれませんけどね。