Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
沈黙すべきか、叫ぶべきか - 独自ブラウザの GPC 実装 - / gpc-war-story
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
marcy731
May 15, 2026
Programming
16
0
Share
沈黙すべきか、叫ぶべきか - 独自ブラウザの GPC 実装 - / gpc-war-story
2026/05/16 大LT2026 春 in Aizu
marcy731
May 15, 2026
More Decks by marcy731
See All by marcy731
Voidと() - 意図を伝える“ユニット型”の世界- / Void vs () -The World of Expressing Intent
marcy731
0
17
WebViewの現在地 - SwiftUI時代のWebKit - / The Current State Of WebView
marcy731
0
310
めざせ!WKWebViewマスター! / WKWebView Master
marcy731
4
3.3k
GitHub Copilotのススメ
marcy731
1
1.4k
Introduction to Memory Management in Swift - Swiftのメモリ管理を知る -
marcy731
0
38
ステートマシンを活用したWebView-ネイティブ間連携へのアプローチ / An Approach to WebView-Native Communication Using State Machines
marcy731
1
1.7k
WebViewをNativeのように使いたい / Using-WebView-like-Native-App
marcy731
2
630
「アプリをつくる仕組み」の構築 / build-system-for-STORES-Branded-Apps
marcy731
0
860
Other Decks in Programming
See All in Programming
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
460
3Dシーンの圧縮
fadis
1
580
inferと仲良くなる10分間
ryokatsuse
1
350
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
2
370
柔軟なPDFレイアウトエディタを支える型システム設計 — Discriminated UnionとConditional Typeの実践
minako__ph
4
1.3k
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
1.5k
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
530
Oxlintのカスタムルールの現況
syumai
5
970
AI駆動開発勉強会 広島支部 第一回勉強会 AI駆動開発概要とワークショップ
hayatoshimiu
0
430
Claspは野良GASの夢をみるか
takter00
0
150
代数的データ型って何が嬉しいの? #frontend_phpcon_do
kajitack
8
3.1k
CSC307 Lecture 17
javiergs
PRO
0
310
Featured
See All Featured
Unsuck your backbone
ammeep
672
58k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
180
エンジニアに許された特別な時間の終わり
watany
107
240k
4 Signs Your Business is Dying
shpigford
187
22k
Statistics for Hackers
jakevdp
799
230k
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.9k
The Pragmatic Product Professional
lauravandoore
37
7.3k
Information Architects: The Missing Link in Design Systems
soysaucechin
0
950
Discover your Explorer Soul
emna__ayadi
2
1.1k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Scaling GitHub
holman
464
140k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2k
Transcript
長谷川 将司 (marcy731) STORES 株式会社 / テクノロジー部門 モバイル開発本部 モバイルPOSグループ マネージャー
個人開発: iOS プライバシー特化ブラウザ Umbric LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 — marcy731 / STORES 1
過去登壇 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 自己紹介 長谷川
将司 (@marcy731) ☐ STORES 株式会社 ☐ テクノロジー部門 / モバイル開発本部 / モバイルPOSグループ ・ マネージャー (iOS エンジニア) ・ 個人開発: Umbric — iOS プライバシー特化ブラウザ ☐ SwiftUI + WKWebView + iOS 26 (Liquid Glass) ・ 「痕跡を残さない」 「見せない」がコンセプト ・ 今日の話の舞台 ・ marcy731 / STORES 2
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 今日の話 Global Privacy
Control (GPC) という機械可読シグナルを WKWebView で出す話 ☐ 実装は JavaScript 10 行 ☐ でも設計判断は分岐点だらけ ☐ WKWebView で GPC を出すのは、表面的に見えるほど簡単じゃなかった ☐ marcy731 / STORES 3
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 1. なぜこの実装をしたのか marcy731
/ STORES 4
Umbric は 2 つの軸でプライバシーを守るブラウザ: しかし、これは全部端末側で完結するプライバシー LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの
GPC 実装 Umbric の世界観 — 「残さない」と「見せない」 ☐ 痕跡を残さない ☐ Cookie / 履歴 / Web Storage は端末に永続化しない ・ WKWebsiteDataStore.nonPersistent() を全タブで使用 ・ SwiftData の履歴はパニックボタンで全削除可能 ・ ☐ 見せない ☐ バックグラウンド復帰時にカモフラージュ画面で隠す ・ Face ID / パスコード でアプリロック ・ 加速度センサで「覗き見されそうな瞬間」を検知 ・ marcy731 / STORES 5
たとえば: でも、その間サイト側は → 「端末側で消す」と「サーバ側で売られない」は、別レイヤ LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC
実装 端末で消しても、サーバ側のデータは残る 履歴を消した ☐ Cookie を消した ☐ 広告 ID と紐づけてユーザを識別 ☐ サードパーティトラッカーに**「あなたのデータ」を売却** ☐ 別端末 / 別ブラウザで同じあなたを再認識 ☐ marcy731 / STORES 6
手段 概要 コスト Cookie 同意バナーで毎回 "Reject All" 表示されたバナー全部に手動で拒否 高 (1
日 50 サイト = 50 回) GPC (Global Privacy Control) ブラウザがブラウザ単位で機械可読に「売らないで」を全サ イトに送り続ける 低 (一度設定すれば 終わり) Umbric は当然 GPC を採用したい → でも実装してみたら、思ったより設計判断が多かったというのが今日の話 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 サーバ側で「売らせない」手段は 2 つしかない marcy731 / STORES 7
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 2. 用語の整理 marcy731
/ STORES 8
globalprivacycontrol.org で定義された 「私はトラッキング・販売・共有されたくありません」 を表明する機械可読シグナル W3C で 2 つの伝達手段が定義されている 1. HTTP
ヘッダ: Sec-GPC: 1 2. JS API: navigator.globalPrivacyControl === true → サイト側はこのシグナルを見て販売・共有を止める義務を負う LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 GPC (Global Privacy Control) とは HTTP ヘッダ: ブラウザが全リクエストに自動で付与 ☐ JS API: サイト側 JS から navigator.globalPrivacyControl で参照できる ☐ marcy731 / STORES 9
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 CCPA とは California
Consumer Privacy Act ☐ カリフォルニア州が 2018 年に制定 / 2020 年に施行した消費者プライバシー保護法 ☐ 通称「カリフォルニア州版 GDPR」 ☐ ユーザに以下の権利を与える: ☐ ☐ 知る権利 (自分のどんなデータが収集されているか) ・ ☐ 削除する権利 (収集されたデータを消させる) ・ ☐ オプトアウトする権利 ← GPC が関わるのはここ ・ 2020 年に CPRA (California Privacy Rights Act) で強化、2023 年施行 ☐ marcy731 / STORES 10
→ GPC を無視 = CCPA 違反 = 罰金対象 LT —
沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 なぜ GPC は CCPA で「効く」のか CCPA 規則 §999.315(c) で、事業者はユーザのオプトアウト意思表示の手段を提供する義務がある ☐ 2021 年、カリフォルニア州 AG (Attorney General = 州司法長官) が: GPC は CCPA 下で有効な opt-out 意思表示として扱う と公式声明を出した ☐ marcy731 / STORES 11
項目 内容 年 2022 年 対象 化粧品大手 Sephora 違反 GPC
シグナルを無視してサードパーティに顧客データ販売 罰金 $1.2M + 是正命令 出典 California AG プレスリリース → 大手企業でも実際に罰金を食らった → GPC は飾りじゃない DNT (Do Not Track, 2009-2019) は法的拘束力ゼロで誰も尊重しなかった GPC はその二の舞ではない LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 執行実例 — Sephora 事件 marcy731 / STORES 12
ブラウザ 既定 備考 Brave ON 全 navigation で Sec-GPC: 1
+ JS API Firefox ON (Private モード) 一般モードは opt-in DuckDuckGo ON 全 navigation Safari (WebKit) 意図的に未実装 WebKit ポジション paper で明示 → Safari だけが**「やらない」と明示**している なぜ?という伏線を、メタ視点のところで回収します LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 各ブラウザの実装状況 marcy731 / STORES 13
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 3. 実装方針を決める marcy731
/ STORES 14
HTTP ヘッダを 1 行足せばいいだけ GET / HTTP/1.1 Host: example.com Sec-GPC:
1 ← これを追加 URLRequest を直接扱うネイティブコードなら、 setValue(_:forHTTPHeaderField:) でたった 1 行 → WKWebView 以外では、本当にそれで終わる LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 最短経路 — のはずだった marcy731 / STORES 15
WKWebView は WebKit プロセスが独自にネットワーク処理を担当 アプリ側から HTTP ヘッダに直接介入する API が存在しない 一応の迂回路
WKNavigationDelegate.webView(_:decidePolicyFor:) → navigationAction を cancel → URLRequest をコピーして Sec-GPC ヘッダ追加 → webView.load(modifiedRequest) で再読込 この迂回路に伴うコスト → Sec-GPC 1 個のためには割に合わない LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ところが WKWebView では ☐ navigation を 2 回発火: cookie / POST / 課金 webhook 二重打ちリスク ☐ ☐ subresource には届かない: fetch / iframe / image に乗らない ☐ marcy731 / STORES 16
W3C 仕様は HTTP ヘッダと JS API の両方を定義している: navigator.globalPrivacyControl === true
幸い、GPC を尊重するサイトの多くはこの JS API も見る (同意管理プラットフォーム = CMP は基本的に JS で動くため) 戦略 WKUserScript で navigator.globalPrivacyControl を true に固定する。 ヘッダは諦めて、JS 層だけで叫ぶ → Umbric Issue #691 で議論し、この中間案を採用 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 じゃあ JS で出す (中間案) marcy731 / STORES 17
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 4. JS 10
行に詰まった戦略 marcy731 / STORES 18
static let globalPrivacyControlSource: String = """ (function () { try
{ Object.defineProperty(Navigator.prototype, 'globalPrivacyControl', { get: function () { return true; }, configurable: false, enumerable: true }); } catch (e) {} })(); """ 10 行未満。シンプル。 ここから、この 10 行に詰まっている設計判断 5 つを解いていきます LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 コード本体 (UserScripts.swift ) marcy731 / STORES 19
// instance に定義 Object.defineProperty(navigator, 'globalPrivacyControl', ...) // prototype に定義 Object.defineProperty(Navigator.prototype,
'globalPrivacyControl', ...) なぜ prototype か GPC を最も見てほしいのは 3rd party の広告 SDK = iframe で動くやつら → prototype 経由は契約(テストでも Navigator.prototype を含むことを assert) LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ポイント ① prototype vs instance ☐ iframe は独自の navigator インスタンスを持つ ☐ ☐ main window の navigator に直接定義しても iframe からは見えない ☐ ☐ Navigator.prototype に置くと、全 frame の navigator が継承で見る ☐ marcy731 / STORES 20
Object.defineProperty(Navigator.prototype, 'globalPrivacyControl', { get: function () { return true; },
configurable: false, // ← これ enumerable: true }); なぜ false か configurable: true だと、ページ側 JS がこう書ける: // 悪意ある page JS Object.defineProperty(navigator, 'globalPrivacyControl', { get: () => false // ← 上書きで偽装 }); → ユーザの「売らないで」が改ざんされる configurable: false でロック → page JS が再 defineProperty しようとすると TypeError で throw ユーザの意思は書き換え不可な契約として固定される LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ポイント ② configurable: false marcy731 / STORES 21
WKUserScript を仕込む側のオプション: let script = WKUserScript( source: UserScripts.globalPrivacyControlSource, injectionTime: .atDocumentStart,
forMainFrameOnly: false // ← デフォルト true なので明示 ) なぜ false か **「主犯が居るのは iframe」**だから、frame 全部に撒く必要がある LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ポイント ③ forMainFrameOnly: false ☐ 広告 SDK / トラッカーは iframe に居る ☐ ☐ forMainFrameOnly: true (既定)だと main frame にしか注入されない ☐ ☐ → 肝心の追跡側に届かない ☐ marcy731 / STORES 22
injectionTime: .atDocumentStart // ← page JS より先 なぜ start か
atDocumentEnd だと: 1. document 読み込み開始 2. page JS が走り、navigator を sniff して結果を保存 3. ← ここで GPC 注入(手遅れ) ページ JS が navigator.globalPrivacyControl を読むタイミングはどこでもありうる → DOM が触れる最初のタイミングで確定する必要がある WKContentWorld のドキュメントにも書いてあるが、順序が全て LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ポイント ④ atDocumentStart marcy731 / STORES 23
(function () { try { Object.defineProperty(Navigator.prototype, 'globalPrivacyControl', { ... });
} catch (e) {} // ← 黙って飲み込む })(); なぜ try-catch か Umbric は atDocumentStart に複数のスクリプトを同居させている (GPC / 広告 DOM ブロック / Canvas spoof / Cookie バナー自動却下 …) GPC が throw → 同じ world の後続スクリプトが全滅 (silent failure) → try-catch で GPC だけ失敗させて、他は生かす LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ポイント ⑤ try / catch でフェイルクローズド marcy731 / STORES 24
@Suite("GlobalPrivacyControlSignal") struct GlobalPrivacyControlSignalTests { @Test("Navigator.prototype に defineProperty している") func definesPropertyOnNavigatorPrototype()
{ #expect(Self.source.contains("Navigator.prototype")) #expect(Self.source.contains("Object.defineProperty")) } @Test("configurable: false でページ JS から再定義できない") func notConfigurable() { #expect(Self.source.contains("configurable: false")) } @Test("try/catch で fail-closed") func wrappedInTryCatch() { #expect(Self.source.contains("try")) #expect(Self.source.contains("catch")) } } JS の実行検証はシミュレータでしかできない LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 テストでピン留め marcy731 / STORES 25
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 5. メタ視点 —
Safari の謎 marcy731 / STORES 26
サイトが Cookie を使わずにユーザを識別する技術 ブラウザから取れる情報を JS で全部集める: → これらの組合せが珍しい = 個別
ID として機能 Chrome 142 / macOS 26 / 2560x1440 / WebGL "Apple M3 Max" ≒ ほぼあなた 1 人 ※ Canvas: 絵を描くための HTML5 API。同じ命令で描いても GPU やフォント差でピクセル値がずれる ※ WebGL: GPU を使う 3D 描画 API。GPU ベンダー / モデル名や描画結果に個体差が出る ※ AudioContext: 音を生成・解析する Web Audio API。出力波形にハードウェア個体差が出る Cookie バナーで Reject しても、こちらはサイレントに走り続ける LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 まず: フィンガープリンティングとは何か User-Agent / OS / 言語 / タイムゾーン ☐ 画面サイズ / インストール済みフォント ☐ GPU renderer (WebGL) / hardwareConcurrency ☐ Canvas / AudioContext で描いた結果のピクセル差 ☐ marcy731 / STORES 27
各情報は「何 bit のエントロピーを持つか」で評価される 世界人口 ≒ 80 億人 = 約 33
bit で個人を一意特定できる User-Agent: 約 10 bit 言語設定: 約 6 bit 画面サイズ: 約 5 bit インストール フォント: 約 14 bit ← これだけでほぼ特定可能 Canvas hash: 約 10 bit タイムゾーン: 約 4 bit 合計 = 約 49 bit >> 33 bit → 「fingerprint bit を 1 つでも減らす」のがプライバシーブラウザの戦い LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 エントロピー (fingerprint bit) の話 marcy731 / STORES 28
各ブラウザの GPC 送出パターン: ブラウザ群 Sec-GPC: 1 を送る? Brave / Firefox-Private
/ DuckDuckGo 送る Safari / Chrome / Edge 送らない 世界の Safari + Chrome シェア = 約 80% GPC を送るブラウザのシェア = 残り 約 20% ユーザ A が Sec-GPC を送る → A は Brave/Firefox-Private/DuckDuckGo のいずれか確定 → ブラウザ識別の bit が +1〜+3 bit 増える → 「GPC を送ること自体」が新しい fingerprint bit になる LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 なぜ「GPC を送る」と識別されるのか marcy731 / STORES 29
WebKit プロジェクト公式ポジション (2020): User-agent extension signals for opting out [...]
increase the fingerprinting surface 要約: 「全員が同じシグナル出さない限り、出してる人を識別できてしまう」 attack surface 最小化の観点では筋が通っている判断 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 Safari の判断 — 「沈黙」 ☐ ユーザの権利を行使する手段としては GPC は正しい ☐ ☐ でも少数派が GPC を送る = その人達が識別される ☐ ☐ Apple は「フィンガープリント表面の最小化」を最優先 ☐ ☐ → 全員沈黙が最適解 ☐ marcy731 / STORES 30
→ 「全員が出す」均一化で、fingerprint bit を 1 つに抑える戦略 LT — 沈黙すべきか、叫ぶべきか —
独自ブラウザの GPC 実装 Brave / Firefox はどう正当化してるか Brave: 「全 Brave ユーザが必ず GPC を出す」 → 漏れるのは「Brave 使ってる」事実だけ → Brave 自体が他で識別されてるので追加情報量ゼロ ☐ Firefox Private: 「全 Private モードユーザが出す」 → 漏れるのは「Firefox Private モード」だけ ☐ marcy731 / STORES 31
方式 fingerprint bit CCPA 有効性 何もしない (Safari) ±0 HTTP ヘッダで送る
(Brave) +1〜+3 (Sec-GPC ヘッダで識別) JS だけで宣言 (Umbric) ±0 (既存の保護機能と同じ bit) △ (JS を見るサイトのみ) なぜ ±0 か → 既存の fingerprint surface 内に「収まる」場所だけで叫ぶ LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 Umbric の選択 — 「JS だけ叫ぶ」中間案 Umbric は既に Canvas / WebGL / AudioContext / navigator.languages を spoof している ☐ JS API を hook してる時点で「Umbric だ」と既に識別される ☐ そこに globalPrivacyControl を追加しても新たな識別軸にならない ☐ 一方、HTTP ヘッダで送ると別の bit が新規に増える ☐ marcy731 / STORES 32
戦略 fingerprint 増加 CCPA 行使 採用例 沈黙 0 × Safari
/ Chrome / Edge 全方位主張 高 (+1〜+3 bit) ◎ Brave / Firefox 既存 surface 内のみ 低 (±0) △ Umbric **「正しいことをやろうとすると逆に識別される」**というジレンマを、 設計判断で割り切る話 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 3 つの戦略を 1 枚で marcy731 / STORES 33
GPC を「半分送って半分送らない」は 逆効果 → fingerprint 対策の鉄則は「ランダム化」ではなく 「均一化」 (Tor / Brave:
全ユーザが同じ generic な値を返す) LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 「ランダムに送ればよくない?」と思った人へ ☐ CCPA 拘束力が中途半端 — 送らなかった時はサイトが「同意」とみなして販売継続 ☐ ☐ ランダム挙動自体が新しい fingerprint bit — そんな挙動するブラウザはほぼ存在しない ☐ ☐ 観察回数が多いと確率分布で露見 — 「50% で送る」が統計的に検出される ☐ marcy731 / STORES 34
実は Umbric は Canvas / WebGL / AudioContext でランダムノイズで撹乱している: //
fingerprint_protection.js data[i] = data[i] + (Math.random() < 0.5 ? -1 : 1) // ±1 ノイズ 属性タイプ 推奨戦略 例 連続値・観察独立 ランダムノイズ Canvas / WebGL / AudioContext 離散 boolean・法的意味あり 送る/送らないを設計判断 GPC 識別性の高い属性 均一化 (全員同じ値) UA / 画面サイズ → GPC は boolean × 観察可能 × 法的意味固定 → ランダム化は両方の悪いとこ取り LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ランダム化が効く属性、効かない属性 marcy731 / STORES 35
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 6. まとめ marcy731
/ STORES 36
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 まとめ ☐ GPC
は CCPA で legal binding がある「売らないで」シグナル ☐ ☐ WKWebView では HTTP ヘッダで送るのが現実的に詰む ☐ ☐ JS API だけで叫ぶ中間案を Umbric は採用 (Issue #691) ☐ ☐ 10 行の JS に 5 つの設計判断: ☐ prototype / configurable: false / forMainFrameOnly: false / atDocumentStart / try-catch ・ ☐ **「正しい主張は、新しい識別軸になりうる」**というジレンマがある ☐ ☐ Safari の沈黙 / Brave の全実装 / Umbric の中間案、全部設計判断 ☐ marcy731 / STORES 37
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 3 つの学び ☐
WKWebView でできないことは JS で逃げる ☐ HTTP ヘッダ注入は詰む。でも W3C 仕様には JS API も書いてある ・ 「仕様の中で逃げ道を探す」が WebKit 制約とのつきあい方 ・ ☐ シンプルなコードほど、判断密度が高い ☐ 10 行の JS の各要素が「なぜそうするか」を持っている ・ ☐ 「正しい」と「安全」は同じじゃない ☐ CCPA で legal binding がある GPC ですら、送ること自体が識別軸 ・ プライバシー設計は「何を守るか」と「何を主張するか」を両方問われる ・ marcy731 / STORES 38
Q A Brave iOS 版は GPC 出してる? 出してます (WebKit 制約は同じ。Sec-GPC
ではなく JS のみ) Sec-GPC ヘッダ実装は本当に無理? URLProtocol を立てて全リクエストを横取り、または NSURLSession の delegate で追加。WKWebView では実用にな らない Apple は将来 GPC API を出す? 出さない可能性が高い (WebKit ポジションが揺らいでいない) iframe で navigator.globalPrivacyControl が継 承されない場合は? sandbox 属性で navigator が再生成される場合あり。実検証が 必要 同じ手法で他の Web API も hook できる? 可能。Umbric は Canvas / WebGL / AudioContext / languages で同じ手法を使用 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 想定 Q&A (先回り) marcy731 / STORES 39
GPC を真面目に出したい方、 WKWebView の HTTP ヘッダ追加で困った方、 このスライドが供養になれば 長谷川 将司 (marcy731)
STORES / モバイルPOSグループ マネージャー GitHub: github.com/marcy731 / X: @marcy731 LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 ありがとうございました marcy731 / STORES 40
LT — 沈黙すべきか、叫ぶべきか — 独自ブラウザの GPC 実装 質疑応答 marcy731 /
STORES 41