はじめまして。
CyberAgent Ameba事業本部 広告プロダクトグループの星と申します。
主に広告計測やPrivacy保護関連を担当しております。
こちらは、CyberAgentメディア管轄の広告プロダクト横軸組織、通称PTAのアドベントカレンダー2020の10日目の投稿になりまして、
最近調査していた「Chrome UA文字列凍結とUA-CHについて」についてまとめさせていただきます。
間違いなどありましたらご指摘いただけると助かります。
UA文字列の凍結とUA-CHについて
まずは以下を参考に概要を
- https://groups.google.com/a/chromium.org/g/blink-dev/c/-2JIRNMWJ7s/m/yHe4tQNLCgAJ
- https://chromestatus.com/feature/5704553745874944
UA文字列の凍結と統一
以下をFreeze・統一したい(削除はしない)
- HTTP RequestのUser-Agent文字列
- navigator.userAgent
UA文字列の例で言うと、以下の様な文字列になるかと思います。
Android Pixel4a Chrome
Mozilla/5.0 (Linux; Android 11; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.110 Mobile Safari/537.36
なぜやるのか?
- Privacy問題(PassiveFingerPrinting Information多い)
- User-Agent文字列に互換性を目的とした虚偽の情報が多く含まれている。
- マイノリティーなブラウザではUser-Agentを偽る状況が起こっており、サイトが正しく表示されないこともある。
- User-Agent文字列を凍結し、User-Agent Client Hints(UA-CH)に置き換える
UA-CH(User-Agent Client Hints)の主な利点
UA-CHの内容自体は後述しますが、以下が主な利点として挙げられています。
- Secureな接続でサーバが要求した時のみに情報を提供する
- Active FingerPrintingとすることで、使用の監視ができる
- いくつかの項目に分かれているので必要な時に必要な情報だけのやりとりになる。(現状のUser-Agent文字列全体が晒されない)
- 専用のフィールドを介するので、誤操作・互換性の問題が発生しにくくなる
- 現在のUser-Agent文字列の大量のレガシー情報を処分できる
- Mozilla/5.0
- like Gecko
- like KHTML
- etc...
UA文字列の凍結時期は?
こちらを見るに、コロナウィルスの影響もあり、
「少なくとも2021年まで」延期されたようです。
ちょっと投稿が古いのですが、私の方ではその後のリリース時期のアップデートは見つけられませんでした。
凍結後も重要なバージョンは更新
- User-Agent文字列の凍結後も「significant version」は引き続き更新されるとのこと。
- 具体的な更新例などは示されていない。
参考 : https://groups.google.com/a/chromium.org/g/blink-dev/c/-2JIRNMWJ7s/m/0hu2ATesAQAJ
UA-CHについて
では、UA-CH(User-Agent Client Hints)についてです。
Chromeの状況
Chromeの状況は以下。
-
Chrome v.84のリリースに含まれている
-
Chrome v.85以降で段階的なroll out
- https://www.chromium.org/updates/ua-ch
- 現時点ではロールアウト対象の拡大は止めているようです
-
こちらの記事公開時点のStableは、Chrome v.87になっています。
UA-CH項目
項目 | 内容 | リクエストヘッダフィールド | デフォルト | Sample値 |
---|---|---|---|---|
brand | ブラウザ名 | Sec-CH-UA | ○ | "Chromium";v="86", "\"Not\\A;Brand";v="99", "Google Chrome";v="86" |
significant version | 重要バージョン | |||
full version | ビルドバージョン | Sec-CH-UA-Platform | x | "86.0.4240.80" |
platform brand | OS名 | Sec-CH-UA-Platform-Version | x | "Android" |
platform version | OSバージョン | Sec-CH-UA-Arch | x | "8.0" |
platform architecture | CPU architecture | Sec-CH-UA-Arch | x | "x86" |
model | デバイスモデル | Sec-CH-UA-Model | x | "Pixel 2" |
mobileness | モバイル判定 | Sec-CH-UA-Mobile | ○ | ?1 |
参考:
UA-CHの取得方法
大きく以下の2つになります
- リクエストヘッダ
- JavaScript API
リクエストヘッダでの取得について
- https必須
- デフォルトで以下のフィールドが送られる
- Sec-CH-UA
- Sec-CH-UA-Mobile
- オプトインすることで以下のフィールドが送られる
- Sec-CH-UA-Full-Version
- Sec-CH-UA-Platform
- Sec-CH-UA-Platform-Version
- Sec-CH-UA-Arch
- Sec-CH-UA-Model
- 高エントロピーな情報はデフォルトでは送られない。
デフォルト以外の取得(オプトイン)方法
metaタグでもできるようですが、ここではレスポンスヘッダのAccept-CHでのオプトインについて。
Cross-Originでリクエストヘッダで取得
Cross-Originでリクエストヘッダでデフォルト以外のHintを取得するには
Origin側のレスポンスヘッダのFeature-Policy(Permissions-Policy)を使ってのdelegateが必要になるようです。
広告だと基本Cross-Originなので、リクエストヘッダで受け取るには配信メディア側の対応が必要になります。
仮に配信メディア側で対応してもらった場合、以下の様な形になるかと思います。
補足
私のほうで試したところ、以下のような動きだったので参考までに。
- Origin側でオプトインしていないと、Cross-Originにdelegateできない(Feature-Policyの指定だけだとダメ)
- Origin側でオプトイン・Cross-OriginへdelegateしていればCross-Origin側でのオプトインは不要。
初回リクエストから乗ってくる
Life-Timeとリセットタイミング
以下になるようです。
- ブラウザセッションの間
- 別のHintが指定されるまで
リクエストヘッダについて
- Http仕様では許可されているが、以前のRequestHeaderでは一般的でなかった以下の様な文字が含まれている。
- double-quotes (")
- equal signs (=)
- forward-slashes (/)
- question marks (?)
- 既存のシステムのどこかでこちらを弾いてしまう可能性がある
- 4xxが返ってくるはず
- Parseには以下のような標準Parserを使うのを推奨
参考 : https://www.chromium.org/updates/ua-ch
GREASE(Generate Random Extensions And Sustain Extensibility)
TLS GREASEの概念を取り込む
brand(Sec-CH-UA)について
- brandに複数の値を含める必要がある。値の少なくとも1つは任意の値。
- 任意の値を追加するとき、値には以下を追加する。
- escaped double-quote
- commas
- semi-colons
- brandの値の順序は時間の経過と共に変化しなければならない。
- Chrome v.86例 (赤字がGREASEにあたる部分になります。)
- "Chromium";v="86", ""Not\A;Brand";v="99", "Google Chrome";v="86"
準拠しているかの基準になり、問題がある場合、早期に気が付けるように。(4xxが返る)
参考 : https://wicg.github.io/ua-client-hints/#grease
JavaScript APIでの取得
navigator.userAgentData.getHighEntropyValues
高エントロピー情報はPromiseを介する。(ユーザに許可を求めたりが想定されるため。)
懸念点
ここまでざっと書いてしまいましたが、以下が懸念として挙げられるかと。
- PrivacyBudgetとの兼ね合い
- とりあえず全部取得としたいところなのですが、以下でPrivacyBudgetで制限される旨の記載もあります。
- https://github.com/WICG/ua-client-hints/blob/master/README.md#persistent-user-tracking
- PrivacyBudgetについてはこちら
- なんらか取得項目を制御できる仕組みは最初から入れておきたい。
- OpenRTB上のフィールドは?
- 広告の場合は結局JavaScriptで取得する必要があるのでは?
- すべての配信メディアやLPにFeature-Policyの設定してもらうこと現実的なのか?
- デフォルトのHint以外も基本必要になるはず。
- JavaScriptのSDKで取得して広告リクエストパラメータに付与することになるのでは?
リクエストヘッダとりあえず確認したい場合
- UA-CH有効にする
- chrome://flags
- 「Experimental Web Platform features」をEnabledに
- 確認サイト
最後に
最後まで読んでいただきありがとうございました。
今後、ブラウザベンダ的にも法律的にもPrivacyに関しての規制がより厳しくなっていくことが予想されます。
ユーザのPrivacyをきちんと守れる状態で、より良い広告配信を実現できるようにしていければと考えております。
また一緒に働いていただける方、絶賛募集中ですので興味のある方はこちらから是非!