Chrome84(beta)におけるUser-Agent Client Hintsの調査
はじめまして。Tech Labの郭です。
Tech Labは弊社の開発効率・運用効率・技術レベルの向上を目的として、業界最新かつ有効な技術を研究・導入するチームです。
今回はブラウザ界隈の最新仕様、User-Agent Client Hints(以下UA-CH)の調査結果を少し共有したいと思います。
UA-CHは Client Hintsの拡張で、仕様自体1はまだ提案中のため、確定していません。 この調査結果は、2020/6/16時点 Chrome84(beta)での検証結果となります。
調査経緯
今年の1/14に現在UA-CHの策定者の1人、GoogleのYoav Weiss氏から一通のGroupメール、「段階的にUser-Agent文字列を非推奨と凍結にする2」の中で、2020中に段階的にUser-Agent文字列を凍結する計画が発表されまして、代替案としてUA-CHが推奨されたことが、調査のきっかけでした。
ところで、最新の状況3では、COVID-19の影響及びUA-CH機能に評価期間を設ける目的で、UA凍結計画は2021年以降に延期されています。
検証方法
Node.js4を使えば一番手軽に検証できるのでおすすめです。
サンプルコード
const https = require('https'); const express = require('express'); const app = express().use(express.static('.')); const fs = require('fs'); // TLS(SSL)自己証明書ファイルを設定する const options = { key: fs.readFileSync('my-key.pem'), cert: fs.readFileSync('my-cert.pem') }; const server = https.createServer(options, app); app.get('/test-ua-ch', function (req, res) { res.writeHead(200, { // UA-CH要求項目を指定する 'Accept-CH': 'UA-Arch, UA-Platform, UA-Model, UA-Full-Version, UA-Platform-Version' }); for (const key in req.headers) { res.write(key + ": " + req.headers[key] + '\n'); } res.end('---end---'); }); const port = 3000; server.listen(port); console.log(`Self-Signed Certificate Server is running: https://localhost:${port}/`);
まだ実験機能のため、手動で Enable
にする必要があります。
chrome://flags/#enable-experimental-web-platform-features
検証用ドメインを /etc/hosts
にを登録しておきます。
127.0.0.1 www.aaa.com
注意事項
3rd-party認証がない自己署名の証明書では、以下のようなリスク提示画面が表示されますが
その場合にキーボードでthisisunsafe
文字列を入力するとページアクセスができるようになります。
stack overflow参考5
あくまでもリスクがある裏技なので動作検証用以外はおすすめしません!
検証結果
取得可能な項目
Chrome84(beta)では取得可能なUA-CH項目が下記通りです。
項目名 | 説明 | 例 |
---|---|---|
sec-ch-ua | ブラウザのブランド及びメジャーバージョン | ... "Google Chrome";v="84" |
sec-ch-ua-arch | CPUアーキテクチャ | ARM64 |
sec-ch-ua-platform | OS名 | Mac OS X |
sec-ch-ua-model | デバイスモデル | Pixel 2 XL |
sec-ch-ua-mobile | モバイルか否か | ?0 |
sec-ch-ua-full-version | UAビルドバージョン | 84.0.4147.30 |
sec-ch-ua-platform-version | OSバージョン | 10_15_4 |
実装コード6でも確認しました。
取得可能な場面
結論は以下の4つです。
TLS(SSL)のみ対応、HTTPは対象外です。
sec-ch-ua
とsec-ch-ua-mobile
の2つ項目は要求しなくても毎回リクエストヘッダの中に含まれて送られます。1st-party ドメインに関して、同じTLS Sessionの中に1回UA-CH情報を要求すればSessionが終了するまで、同一FQDNから全てのリクエストヘッダの中にUA-CH情報が含まれて送られます。
3rd-party ドメインに関して、UA-CH情報を要求しても送られません。
検証ケースをシーケンス図で表すとこんな感じです。
↑ 1st-party ドメインのページ内検証です。
ページのレスポンスでUA-CH情報を要求してから、ページ内の同一FQDNからのリクエストのヘッダの中にUA-CH情報が入っていることを確認しました。
↑ 1st-party ドメインの別ページ検証です。
1st-party ドメインに対して、同一TSL Session、かつ同一FQDNの別ページからのリクエストのヘッダの中にUA-CH情報が入っていることを確認しました。
↑ 3rd-party ドメインのリダイレクト検証です。(リダイレクト先は同一FQDNの画像)
3rd-party ドメインの www.bbb.com
に対して、UA-CH情報を要求しても送られないことを確認しました。
やはり 3rd-party ドメインに対して、プライバシー制限が掛かっているようです。
↑ クリック&リダイレクトの検証です。(リダイレクト先は同一FQDNのページ)
クリックすると、www.bbb.com
が 1st-party ドメインになるのでUA-CH情報の取得ができます。
レスポンスでUA-CH情報を要求してから、リダイレクト先のリクエストヘッダの中にUA-CH情報が入っていることを確認しました。
おわりに
以上、UA-CH あたり検証した結果の共有でした。いかがでしょうか。
Googleが提案している広告モデルとプライバシーの両立を目指す仕組みPrivacy Sandbox7の中の一つ、Federated Learning of Cohorts (コホート連合学習)8でもSec-CH-Flock
という別のClient Hints を利用する予定なので、Client Hints 周りへの注目はますます高まると思います。
-
https://groups.google.com/a/chromium.org/g/blink-dev/c/-2JIRNMWJ7s/m/yHe4tQNLCgAJ?pli=1↩
-
https://groups.google.com/a/chromium.org/g/blink-dev/c/-2JIRNMWJ7s/m/u-YzXjZ8BAAJ↩
-
https://stackoverflow.com/questions/7580508/getting-chrome-to-accept-self-signed-localhost-certificate↩
-
https://github.com/chromium/chromium/blob/master/third_party/blink/common/client_hints/client_hints.cc#L21↩
-
https://www.chromium.org/Home/chromium-privacy/privacy-sandbox↩