1 ポイント 投稿者 GN⁺ 2024-10-08 | 1件のコメント | WhatsAppで共有
  • uBlock Origin のコミットでは、Firefox のネットワーク処理における CNAME uncloaking のフローを書き直し、DNS 参照で得た IP を details.ip に反映するように変更
  • 既存の cnames Map キャッシュはなくなり、dnsListdnsDictdnsWritePtr ベースの 256 件リングバッファ60000ms TTL キャッシュに置き換え
  • DNS 参照には browser.dns.resolve(hn, [ 'canonical_name' ]) を使用し、結果の canonicalNameaddresses[0] をそれぞれ CNAME と IP として利用
  • CNAME 例外処理は 1st-party、ignore list、root document 条件を維持し、IPv4 アドレスや [ で始まるホスト名は 再参照の対象外 とする
  • Chromium の最小バージョンは 80.0、Opera の最小バージョンは 67.0 に引き上げられ、隠し設定の cnameMaxTTL デフォルト値は削除

Firefox DNS キャッシュ構造の再設計

  • platform/firefox/vapi-background-ext.js の CNAME uncloaking 関連コードが、グローバル Map 中心の構造からクラス内部の DNS キャッシュ 構造に変更
  • 既存の cnameUncloakEnabled グローバル状態と cnames Map の代わりに、次のフィールドでキャッシュを管理
    • dnsList: リングバッファ
    • dnsWritePtr: 次の書き込み位置
    • dnsMaxCount: 最大 256
    • dnsDict: ホスト名からリングバッファインデックスへのマッピング
    • dnsEntryTTL: 60000ms
  • コンストラクタでは canUncloakCnamescnameUncloakEnabledtrue で初期化

リクエスト処理フロー

  • onBeforeSuspendableRequest(details) はリクエスト URL からホスト名を取り出した後、まず dnsFromCache(hn) でキャッシュを確認
  • キャッシュされた DNS 項目に ip があれば、details.ip に設定
  • 基本の super.onBeforeSuspendableRequest(details) 呼び出し結果がキャンセルやリダイレクトなどで終了した場合、その結果をそのまま返却
  • キャッシュされた DNS 項目が Promise でなければ、onAfterDNSResolution(hn, details, dnsEntry) で後続処理を継続
  • DNS 再参照条件を満たさない、または details.proxyInfo?.proxyDNS がある場合は、追加の DNS 処理を行わない

DNS 参照と保存方式

  • dnsShouldResolve(hn) は、空のホスト名、[ で始まるホスト名、IPv4 アドレス形式を DNS 参照対象から除外
  • dnsResolve(hn, details) はリングバッファの現在位置にホスト名を登録し、dnsAPI.resolve(hn, [ 'canonical_name' ]) を呼び出す
  • 参照成功時は dnsToCache(hn, rec, details) が実行され、失敗時は dnsToCache(hn) で空の項目をキャッシュに残す
  • dnsToCache は新しいキャッシュ項目に hn と有効期限時刻を保存
    • cnameFromRecord が値を返せば dnsEntry.cname に保存
    • ipFromRecord が値を返せば dnsEntry.ip に保存
  • dnsFromCache はキャッシュ項目が Promise ならそのまま返し、期限切れ項目は dnsListdnsDict から削除

CNAME と IP の反映条件

  • cnameFromRecord(hn, record, details)record.canonicalName がない、または元のホスト名と同じ場合は CNAME を返さない
  • cnameIgnore1stParty が有効なら、CNAME と元のホスト名のドメインが同じ場合は除外
  • cnameIgnoreList がある場合、その正規表現にマッチしない CNAME は除外
  • cnameIgnoreRootDocument が有効なら、リクエストホスト名が details.documentUrl || details.url のホスト名と同じ場合は除外
  • ipFromRecord(record)record.addresses が配列で空でない場合、最初のアドレス addresses[0] を返す

URL の書き換えと後続フィルタリング

  • onAfterDNSResolution は DNS 項目に CNAME があり、cnameUncloakEnabled が有効なら uncloakURL で URL を書き換える
  • URL を変更する際、既存の URL は details.aliasURL に保存し、新しい URL は details.url に反映
  • DNS 項目に IP があり、現在の details.ip と異なる場合は details.ip を更新
  • CNAME 書き換え または IP 変更が発生した場合にのみ、ベースクラスの onBeforeSuspendableRequest(details) を再度呼び出す
  • uncloakURL は URL 内のホスト名位置を見つけて CNAME に置き換え、cnameReplayFullURL の値に応じて URL 全体を連結するか、パス手前までを維持する

設定と manifest の変更

  • setOptions から cnameMaxTTL の処理を削除
  • オプション変更時は既存の cnames Map 初期化の代わりに dnsList.fill(null)dnsDict.clear() で DNS キャッシュを空にする
  • src/js/background.js の隠し設定デフォルト値から cnameMaxTTL: 120 を削除
  • platform/chromium/manifest.jsonminimum_chrome_version73.0 から 80.0 に変更
  • platform/opera/manifest.jsonminimum_opera_version60.0 から 67.0 に変更

1件のコメント

 
GN⁺ 2024-10-08
Hacker Newsのコメント
  • タイトルが間違っているように思える。uBlock Origin はすでに何年も前からこの機能をサポートしていて、ただし Firefoxでのみ 可能だった
    今回の件はまったく新しい機能というより、そのコードのリファクタリングに見える

    • 今もサポートしているし、以前からサポートしていた :P
    • 単なるリファクタリング以上のように見える。これで実際のリクエストが送られる前に、IPベースのブロック をより早い段階で行えるようになったようだ
      ただし、1つのドメインに複数のIPがある場合、ブラウザがどのIPを選ぶかは分からないので、完璧ではない
    • タイトルをページタイトルに戻した。投稿タイトルは「uBlock Origin supports filtering CNAME cloaking sites on Firefox now」だった
      もっと正確で中立的なタイトルを提案してくれるなら、また変更できる。ただ、追加の文脈がない GitHub コミットは通常 HN スレッド向きではあまりない
  • まだ直接の被害は受けていないが、Chrome が本当に uBOを排除したら 乗り換えられるように、すでに拡張機能を Firefox 向けに手直ししている

    • 「もし」ではなく「いつ」の問題だ。2020年の時点ですでに「いつ」だったし、実際にその時が来つつある
      あと数回のリリースで到達するだろうから、準備しておくべきだ
    • 家族を Brave に移している。違いはほとんど感じないし、ブラウザがユーザー主導のコンテンツフィルタリングを今後もサポートし続けるという確信もより強い
    • すでに Canary リリース では削除されている
    • 「拡張機能を Firefox 向けに書き直す」というのがどういう意味か分からない。Firefox も同じ API を使っている
      せいぜい background.service_workerbackground.scripts に変える程度で、文字どおりキー名を変えるだけで済む
    • 詳しくない人のために聞くが、uBO とは何で、ほとんどの拡張機能にどんな影響があるのか?
  • uBlock Origin は Firefox をより優れたものにしている要素であり、Chrome などではなく Firefox を使う大きな理由の1つだ
    インターネットを実際に閲覧可能な状態にしてくれる

    • 数年前にこの組み合わせに移行したが、離れる理由は一度も見当たらなかった。Android のスマートフォンでも同様で、私が見た中では唯一まともに使えるモバイルWeb体験だ
      10年以上、いくつかのサイトで表示の問題はあったが、そうしたサイトは Chrome でも問題があった
      個人的には広告は現代社会のがんのような存在だと思っている。罪のない嘘とそうでない嘘、操作が入り混じっていて、そこに莫大な金が流れているという点で、むしろまったく尊重に値しない
    • Mozilla が 広告会社 になりつつあるので、その点は変わるかもしれない
    • Brave と Firefox の両方を使ってみたが、正直大きな違いは感じなかった。それでも、理念と非営利組織発という点から Firefox をより好んでいる
      Brave も品質の高いプロジェクトなのでバックアップとして使っており、ときどきウィンドウ分割とずっと優れたタブ管理のために Vivaldi も併用している
  • CNAME クローキング とは、広告サイトがワイルドカードレコードを指すランダム生成のサブドメインを使うことを意味するのか?

    • それも一部だ
      通常、contentsite.com を訪れると広告は adsite.com から配信される。広告ブロックのルールで adsite.com を止めれば、広告は表示されない
      CNAME クローキングは、メインサイトが adsite.contentsite.com のようなサブドメインを adsite.com に向ける方式だ。すると広告ブロッカーは、正規サイトに属しているように見える何百万ものサブドメインをブロックしなければならないという、ほぼ不可能な仕事を負わされる
      正規サイトはサブドメインを変え続けることができ、広告ブロッカーにはどのサブドメインが正規コンテンツでどれが広告なのか知る方法がない。しかも、同じドメインからコンテンツが配信されるため、一部の Cookie ポリシーを回避してユーザーをより追跡しやすくもなる
      今回のアップデートでは、解決されたIPを基準にフィルタリングするルールを設定できるようになる
    • そのとおり。広告および分析プロバイダーは、サードパーティCookie保護 を回避するためにこの方式を使い始めた
  • これは Manifest V3 がなぜいまひとつなのか をよく示す例だ。定義上、この種のことはできず、実行時コードベースのヒューリスティクスも不可能だ
    広告主との軍拡競争だが、Google は両陣営に武器を売るディーラーだ。ユーザーが勝つために必要なものは与えないだろう

    • 宣言的な Manifest V3 API に、こうした機能を提供できない理由はない。コミット内容を正しく読めているなら、実際のサーバーに何も送る前にリクエストフローへよりうまく統合し、実際に使われるIPアドレスを基準にブロックする形で、より適切に動作する可能性もある
      もちろん、これらすべてはブラウザベンダー、つまり Google がこの API を追加したいかどうかにかかっている。「実行時コード」による命令的な処理が可能なら、ブラウザメーカーが組み込みサポートを入れる前に、ユーザー空間でイノベーションを起こせる
    • 技術的には Manifest V3 自体は、ブラウザが拡張機能に提供する API とは別物だ。Firefox では Manifest V3 はブロッキング Web リクエスト[1] とともにサポートされており、これは「Manifest V3」以前からあるフィルタリング API だ
      したがって、特定の機能が「定義上」不可能だというのは誤りだ
      [1] https://blog.mozilla.org/addons/2022/05/18/manifest-v3-in-fi...
    • Chrome を捨てて Firefox を受け入れればいい
  • CNAMEクローキング たとえば、SaaSプロバイダーAが企業Qに優れた広告トラッキングソフトウェアを提供しようとしているとする。
    従来のやり方であれば、Aは企業Qのウェブサイト https://q-company.example に、たとえば https://A-ads-tracking.example のスクリプトを挿入するよう求めていたはず。
    すると、uBlock Originが使うブロックリストには「A-ads-tracking.example ドメインへのリクエストを遮断せよ」のようなルールが追加され、広告はブロックされる。
    CNAMEクローキングでは、SaaSプロバイダーAは広告トラッキングサービスを A-ads-tracking.example ドメインではなく、たとえば 29.1.2.3 のような特定のIPアドレス上に置く。さらに重要なのは、SaaS Aが企業Qに対して q-company.example のサブドメインを作成し、そのCNAMEレコードが 23.1.2.3 を指すように要求する点である。media.q-company.example のようなもっともらしい名前を付ける。
    Q社がそのCNAMEを設定し、ウェブサイトに media.q-company.example のスクリプトタグを追加すると、SaaS Aはそのサイトのすべてのユーザーを追跡できる。この迂回レイヤーのせいで、Q社の運営者と公開ブロックリストの間には、事実上終わりのないいたちごっこが生まれる。
    この問題を避けるには、uBlock Originのような拡張機能を動かすソフトウェアが、ブラウザのリクエスト先ドメインだけでなく、そのドメインの実際のIPアドレスも見られる必要がある。このコミットは、その動作を可能にすること、あるいは少なくともそのコードがより適切に動作するようにすることに関係しているように見える。

    • 正確には少し異なる。名前のとおり CNAME を使うのであって、IPを指すAレコードではなく、別のレコードを指すレコードである。
      たとえば media.q-company.exampleq-company.ads-tracking.example を指すCNAMEで、その次に q-company.ads-tracking.example がIPを返すAレコードを持つ、といった形になる。
      ブラウザがその中間DNS名を拡張機能に提供するのかは分からない。だから、uBlockのようなものはIPリストに依存せざるを得ないかもしれないが、piholeのようなDNSベースのフィルタリングなら、ads-tracking.example に対するルールでそのままブロックできる。
      いずれにせよ、ブラウザベースとDNSベースのマルウェアブロッカーの両方を使うのがよい。
    • だからこそ、uBlockの高度モードで すべてのJavaScriptをブロック し、サイトが正しく動作するまで表示されたスクリプトを少しずつ許可リストに入れていくのがよい理由になる。
      遅くてミスもしやすいが、慣れれば楽になり、この種のくだらない手口には完全に耐性がつく。
  • ChromeはuBOを止める予定なのか? 最新状況を常に追っているわけではない。
    サードパーティCookieは今では許可することになったと理解しているので、ひょっとすると可能性はあるのかもしれない。

    • uBO自体を止めるのではなく、新しいプラグインAPIである Manifest V3 を導入することで、uBOが動作できていたブラウザ機能を削除している。
      uBOが、読み込ませてはいけないものを識別し、その後で実際に読み込まれないようにするために必要な中核APIを取り除いている。
      Googleはこれを「性能」や「セキュリティ」のためだと主張している。もちろん、実際に大きく影響を受ける唯一の「性能」や「セキュリティ」とは、有害または広告関連のダウンロードが始まる前に、それを識別し、横取りして、中止する能力のことだ。
    • ブラウザを更新しないのも危険だ。Firefoxに移行 して、アップデートも受けつつuBOも完全にサポートされる方がはるかによい。
    • ブラウザ独占に対する悪い世論が一気に噴き出すのを避けるため、長い期間をかけてゆっくり段階的に削除している。しかし、そのスケジュールはすでに6月から始まっている。
      https://developer.chrome.com/docs/extensions/develop/migrate...
      https://www.bleepingcomputer.com/news/google/google-chrome-w...
    • 現時点では、Manifest V2をサポートするChromiumブラウザ向けに、Chrome Web Store にはまだuBlock Originがある。
      Manifest V3のみをサポートするChromiumバージョンを使うと非表示になる。
    • 正直なところ、アメリカが露骨な独占企業を法廷に引きずり出そうとする政権を維持し続けるかどうかにかかっている可能性が高い。
  • 一部のDNSサーバーには、サーバーが解決したCNAMEのように動作する機能があるのでは? 管理者は別のDNS名を指すレコードを入れるが、クライアント側からは単にAまたはAAAAレコードしか見えない、という方式のこと。

    • ALIASレコード のことだと思う。
  • uBOにはこの機能がかなり前からあった。1.34.0 からで、高度な設定では1.25.0からだった。
    https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings#u...
    だいたい2021年ごろだったと記憶している。

  • Brave、Edge、Operaでの uBOの状況 はどうなのか?

    • 挙げられた独占系ブラウザ2つには興味がないが、Braveはできるだけ長くManifest V2を部分的にサポートし、uBOとの互換性を維持する予定だ。
      https://brave.com/blog/brave-shields-manifest-v3/
      ただし必須というわけではない。Braveには独自の内蔵広告ブロッカーがかなり強力に組み込まれており、最後に確認した時点ではネイティブコードにコンパイルされていてuBOより性能も高く、同じ広告リストも完全にサポートしていた。