世界を動かす技術を、日本語で。

Androidにおけるローカルホストを利用した隠れたWebからアプリへのトラッキング

概要

  • MetaとYandexによる新しい追跡手法の発見
  • Android端末上の主要アプリがローカルポートで静かに通信
  • ブラウザのメタデータやクッキーがアプリに送信される仕組み
  • 既存のプライバシー保護策を回避する危険性
  • 悪意のあるアプリによる盗聴リスクの増加

MetaとYandexによる新しいAndroid追跡手法

  • Meta(Facebook, Instagram)Yandex(Maps, Browser等) のAndroidネイティブアプリによる追跡手法の発覚
  • これらのアプリが 固定ローカルポート で静かに待ち受ける仕組み
  • Meta PixelYandex Metrica のJavaScriptが数千のWebサイトに埋め込まれる現状
  • ユーザーの モバイルブラウザ でスクリプトが読み込まれると、同一端末内のネイティブアプリへ localhostソケット通信 で接続
  • 通信経路として、 ブラウザのメタデータ・クッキー・コマンド の送信
  • ネイティブアプリは Android Advertising ID(AAID) やユーザーIDなどの端末識別情報へプログラム的にアクセス
  • この手法により、 Web閲覧セッションWebクッキーユーザーID の紐付けが可能
  • 結果として、スクリプトが埋め込まれたWebサイトの訪問者の 匿名性が失われる 危険性

プライバシー保護策の回避とリスク

  • この Web-to-App ID共有手法 は、一般的なプライバシー保護策
    • クッキー削除
    • シークレットモード(Incognito Mode)
    • Androidのパーミッション制御
    • これらを 容易に回避 する仕様
  • さらに、 悪意のあるアプリ が同様の手法でユーザーのWeb活動を 盗聴 する危険性
  • ユーザーの行動履歴ID情報の漏洩 リスクの増大

追加資料の概要

  • Yandex がローカルホストリクエストを送信する様子の動画資料
    • 左:Android端末のブラウザのリモートデバッグ画面
    • 右:Android端末の画面(検証用アプリとブラウザ表示)
  • Meta Pixel がローカルホストSTUNリクエストを送信する様子の動画資料
    • 左:ネットワークトラフィック監視ツールWireshark
    • 右:Webサイト閲覧中のブラウザ画面
    • Android端末(Pixel 7)でのみリクエストが発生する挙動
  • Meta Pixel がローカルホスト通信で接続する ポート・プロトコル パラメータの図
  • Meta Pixel による SDP Munging で_fbpクッキー値を挿入する様子の図
  • Meta PixelSTUN で_fbpクッキー値をモバイルアプリに渡す手法の図

まとめ

  • Androidユーザーの プライバシー侵害 リスクの高まり
  • MetaYandex による Webとアプリ間のID連携 の新手法
  • 既存のプライバシー対策の限界 と新たなセキュリティ課題

Hackerたちの意見

関連: https://news.ycombinator.com/item?id=44169115

ありがとう!マクロ拡張:MetaとYandexがAndroidユーザーのウェブブラウジング識別子を非匿名化してる - https://news.ycombinator.com/item?id=44169115(4時間前、126件のコメント)

これはかなり明らかな攻撃手法だね。ブラウザが最初からこれを許可してたのが驚きだよ。ローカルホストにSTUN/TURNする理由が思いつかないし。ローカルホスト以外にも、トラッカーはブラウザが使える他のIPアドレスを使ってアプリをバインドしたり、トラフィックを送ったりできるからね。今やこのメカニズムが知られて(広く実装されてる)から、ユーザーにトラッキングの試みを通知するアプリを作ることもできるよ。必要なのは、リストにあるUDPポートを開けて、UDPトラフィックが来たら通知を送ることだけ。ちょっとした冗談で、Androidを改造して、アプリごとに異なる一時的なIPv6アドレスを配布し、こういうことのせいで露出するかもしれない他のインターフェースをセグメント化できるか考えてたんだ(IPv4接続のためにCLATや他のフォールバックメカニズムを使う)。こういうトラッキングがあからさまになるのはおかしいから、これは理論上の問題だと思ってたけど、Facebookがまたしても俺を間違ってると証明してくれた。EUの規制当局がこれに気づいて、同意なしにトラッカーを読み込むウェブサイトに罰金を科すようになればいいんだけど、実際にはそんな能力はないだろうな。

アプリごとに異なる一時的なIPv6アドレスを配布し、露出するかもしれない他のインターフェースをセグメント化する うん、でも(私の知る限り)標準では無理だね(セキュリティ重視のROMがこれをサポートしてる場合を除いて)。カーネルはネットワークネームスペースをサポートしてるし、それを使う方法についてのドキュメントもたくさんある。でも、一般的なAndroid ROMが必要なツールを持ってるかはわからない。大まかに言うと、zygoteがPIDを変更するロジックをパッチして、ネットワークネームスペースを設定して切り替える必要がある。

Androidを改造して、アプリごとに異なる一時的なIPv6アドレスを配布するのは、AFAIK(私の知る限り)Androidのロードマップに載ってるし、彼らがDHCPv6をサポートしたくない主な理由の一つなんだ。各アプリに独自のIPを持たせたいんだよ。

別のHNスレッドに書いたコメント [0] (ただし、これが元のやつね): ウェブアプリがLANリソースにアクセスするのは、今でもブラウザによって驚くほどオープンな攻撃ベクターだよ。uBlock Originには「LANへの外部侵入をブロック」というフィルターリストがあって、これは「プライバシー」フィルターの下にあるんだけど [1]、新規インストールでは有効になってないから、明示的にオプトインしないといけないんだ。それに、figma.compcsupport.lenovo.comみたいなドメインにはいくつかの例外がある([1]で確認できる)。Discordがアプリがインストールされているかを確認するために高い番号のポート(6463-6472)をスキャンするような半正当的な使い方もあるけど、主に悪意のある行為者によるフィンガープリンティングに使われてる。例えば、eBayはフィンガープリンティングのためにLexisNexisスクリプトを使ってポートスキャンを行っている(2020年にはそうしてたけど、今もやってるかは不明)。これは詐欺防止のためだと言われてる [2]。LANに侵入するウェブリクエストをブロックするためのクールなFirefox拡張「Port Authority [3][4]」にも少し貢献したんだ。これを使うと、ブロックしたポートスキャンの試みが表示される。uBlock Originのフィルターリストだけでもほぼ同じ結果が得られるけど、ブロックされた試みをもっと詳細に見るのは面白いと思う。ただ、uBlockとPort Authorityの両方がWebExtensionsのwebRequest [5] APIを使ってHTTP[S]/WS[S]リクエストをフィルタリングしてるから、特に言及されたarcaneなwebRTCトリックがこのAPIにさらされるリクエストにどのように関連するのかは不明だ。もしかしたら、利用可能なWebExtensionsのブロッキング手法を回避するかもしれないから、良くないね。0: https://news.ycombinator.com/item?id=44170126 1: https://github.com/uBlockOrigin/uAssets/blob/master/filters/... 2: https://nullsweep.com/why-is-this-website-port-scanning-me/ 3: https://addons.mozilla.org/firefox/addon/port-authority 4: https://github.com/ACK-J/Port_Authority 5: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web...

半正当的な使い方もある、例えばDiscordがアプリがインストールされているかを確認するために高い番号のポート(6463-6472)をスキャンするのは、私はこれを正当な使い方とは考えないな。ウェブサイトがどのアプリをインストールしているかを知る必要はないよ。

あなたのDNSサーバーがlocalhostに解決しないのも、追加の防御ラインとして役立つかもしれないよ。

*: Meta Pixelスクリプトは2024年10月にHTTPで送信されているのが最後に見られたけど、FacebookとInstagramのアプリは今でもこのポートをリッスンしてる。HTTPのためにポート12388でもリッスンしてるけど、12388に送信しているスクリプトは見つかってない。: Meta Pixelスクリプトはこれらのポートに送信するけど、Metaアプリはまだそれらのポートでリッスンしてない?この挙動はアプリの段階的な展開が原因かもしれないと推測してる。だから、他のアプリが偽のメッセージでこれらのポートにデータを送信することはできるのかな?科学のために色々やるのが好きな友達のために聞いてるんだ。

iOSにも似たようなことある?ランダムなアプリが「ネットワーク上のデバイスを見つける」って聞いてくるといつも不思議に思う。

そのページで答えが書いてあるよ。

とはいえ、iOSのブラウザとネイティブアプリ間でのデータ共有は技術的には可能だよ。

可能だけど、iOSの制限されたバックグラウンドプロセスモデルのせいで、実用的じゃないかもしれないね。バックグラウンドタスクは一般的に、必要なことをすぐにやって終了することが期待されてて、無限に動き続けることはできないんだ。定期的なタスクはOSによってスケジュールされて、アプリからのスケジューリングリクエストは、プロセスがちゃんとしてれば(速くて、リソースをあまり使わず、クラッシュせず、頻繁に動かない)通りやすいけど、調子が悪いプロセスはあまり動かされない。音声を再生してるって報告することで自分を開いたままにしてるアプリは、この問題を回避できるかもしれないけど、それでも不安定だね。ユーザーがメディアを再生することが多いから、バックグラウンドのアプリはサスペンドされて、最終的にはメモリから追い出されちゃうし。

これってプロファイルを越えてできるの?それだと企業にとって大きなセキュリティ問題になるよ。簡単にテストしたら、Userlandアプリで8080を提供すると、両方のプロファイルからアクセスできた。だから、多分そうだね。これって、個人プロファイルに感染したアプリが、別のプロファイルで訪れたサイトとデータを交換できるってことだ。

でも、そのサイトがローカルポートにバウンドされた(認証されていない)サービスと特に通信する場合だけだよね?

大手テックのアプリをインストールしない理由の一つだね。どうしても必要な時だけウェブサイトを使うべき。ウェブサイトは使いにくいし、使う気を失わせるし、もっとサンドボックス化されてるからね。

どのMetaアプリがポートを開くのかはよくわからないけど、例えばSamsungのスマホにはいくつかのMetaアプリがプリインストールされてるよね。確か、Facebookアプリを削除するだけじゃ不十分で、アプリとしては見えない別のサービス(com.facebook.servicesとか)がインストールされてるんだ。それはADB/UADみたいなものでデータパーティションからしかアンインストールできないよ。もしくはiPhoneかPixelを買うしかないね。

EUの罰金に関するスレッドでよく見かけるのが、「EUはアメリカのテック企業に罰金を科して、すぐに金を稼ごうとしてる!」っていう意見。こういうことをやめるのも一つのアイデアかもね。これに対して数十億ドルの罰金を見るのもいいかも。

なんで全てのブラウザ、デスクトップでもモバイルでも、localhostへのクロスオリジンアクセスを全部ブロックしないの?

一つには、「マザーボードのウェブサイトからBIOSをアップデートする」アプリが全部壊れちゃうからだと思う。多分、正当な使い方もあるだろうけど、思いつくのが難しいな。

リソースやJSについてはそうしてると思ってたから、MetaはWebRTCを使わざるを得ないんじゃないかな?Yandexの方は、CORSがヘッダーにあるものだけを単純にチェックしてるから、通っちゃうのかな?

YandexのHTTPSって、アプリに証明書のプライベートキーを含めてるってこと?だから、localhostで動いてるもの(またはDNSが汚染されたネットワーク上)でyandexmetricaサイトを偽装できちゃうってこと?ログにその証明書があるよ: https://crt.sh/?q=yandexmetrica.com