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

ユーザーのローカルネットワークへのアクセスを制限するサイトに関する提案

概要

Chrome Secure Web and Networkチーム によるローカルネットワークアクセス保護の提案 パブリックサイト からのローカルデバイス攻撃リスクへの対応策 ユーザー許可 によるローカルネットワークリクエスト制御 既存デバイスの変更不要 でサイト側のみの対応が主 安全性向上 とユーザーコントロール強化を目指す設計

Chrome Local Network Access 提案概要

  • Chrome Secure Web and Networkチーム による初期設計案
  • パブリックウェブサイト がユーザーのローカルネットワークにアクセスし、 CSRF攻撃やデバイス悪用 が可能な現状への対応
  • 例: evil.com がHTTP経由でプリンター等を攻撃
  • ローカルネットワークアクセス (Local Network Access)導入による、ユーザー明示許可制の新設
  • Private Network Access(PNA) の過去提案を基礎としつつ、 事前許可 方式に変更

目的と非目的

  • 脆弱なローカルデバイス やサーバをウェブ経由で攻撃されるリスクの低減
  • ユーザーが期待・許可 した場合のみ、パブリックサイトからローカルデバイスと通信可能に
  • OSレベルのローカルネットワークアクセス許可 との整合性も重視
  • 既存のワークフローやサービスの破壊 は最小限に抑制
  • ローカルネットワーク上のHTTPS問題の解決 は本仕様の対象外

ユースケース

  • ユースケース1:一般ユーザー
    • ローカルネットワーク上に外部からアクセスされることを想定していない場合
    • ブラウザはデフォルトでJavaScriptやサブリソースリクエストを許可しない
  • ユースケース2:ローカルデバイスのセットアップ・制御
    • IoTデバイスやルーターの初期設定など
    • メーカーサイト経由でユーザーのローカルデバイスと通信
    • デバイス側の複雑なウェブサーバー実装不要

提案するソリューション

  • 新しい「ローカルネットワークアクセス」権限 でリクエストを制御
  • 許可されていないオリジン からのローカルネットワークリクエストはブロック
  • アドレス空間 を3層で定義
    • loopback (localhost等)、 local (プライベートIP、.localドメイン)、 public
  • ローカルネットワークリクエスト の定義
    • 公開サイト→ローカル、公開サイト→loopback、ローカル→loopback等の境界越え

許可プロンプトの挙動

  • サイトがローカルネットワークリクエストを発行時、 権限未取得ならユーザーに許可を要求
  • ユーザーが拒否した場合は リクエスト失敗
  • ユーザーが許可した場合のみ リクエスト継続
  • 混在コンテンツ(Mixed Content) の一部例外適用

ユースケースへの適用例

  • 予期しないアクセス
    • 例:example.comがfetch("http://192.168.0.1/routerstatus")を実行
    • ブラウザが許可プロンプトを表示し、ユーザーが拒否すればアクセス不可
  • ローカルデバイス制御
    • メーカーサイトがfetch()でローカルデバイスにアクセス
    • 必要に応じて targetAddressSpace="local" 等をfetch()に指定
    • 初回のみユーザーに許可を要求、許可すれば従来通り利用可能

詳細設計とFetch API連携

  • Fetch API の仕様にDNS解決詳細は非統合
  • Happy Eyeballs 等によりIP空間のまたがり時に非決定的挙動も
  • 接続取得後 にローカルネットワークアクセスチェックを実施
  • セキュアコンテキスト 外からのリクエストはブロック
  • fetch()のoptionsにtargetAddressSpaceパラメータ 追加提案
    • 例:fetch("http://router.com/ping", { targetAddressSpace: "local" })
    • 指定したアドレス空間と実際のIP空間が不一致ならリクエスト失敗

混在コンテンツ(Mixed Content)対応

  • ローカルネットワークHTTPS未普及 による混在コンテンツ問題
  • fetch()で private IPや.localドメイン、targetAddressSpace指定 時のみ混在コンテンツチェックをスキップ
  • 接続後、ローカルネットワークアクセス権限がなければブロック
  • targetAddressSpace で明示的にローカル・loopback指定可能
  • 指定先が実際にローカルでない場合はリクエスト失敗で安全性確保

今後の課題と展望

  • デバイス側の変更不要 で展開しやすい設計
  • ユーザー体験の向上セキュリティレベルの強化 を両立
  • HTTPSローカル通信問題より細かい権限管理 の今後の検討課題
  • GitHubリポジトリ にてフィードバック受付中(https://github.com/explainers-by-googlers/local-network-access/issues)

Hackerたちの意見

これ、Metaがネイティブアプリとウェブサイトの間で、特にAndroidでローカルホストを通じて密かに識別コードを共有するのに役立ちそうだね。

何年も前にNPAPIプラグインが削除されて以来、公共のウェブサイトで使うことを目的としたローカルにインストールされたソフトウェアは、ローカルホストでHTTPサーバーを立てる必要があるんだ。もしこの使い方が面倒になったり、完全に潰されたりしたら本当に困るよね。(代わりに、ブラウザ開発者が本当の代替案を提供してくれればよかったんだけど、もう遅いかな。)

これは本当じゃないと思う。https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Web... が存在するから。拡張機能をインストールする必要があるけど、NPAPIとの比較ではそれは妥当だと思うよ。

ほとんどのソフトウェアは、OSにプロトコルハンドラーを登録するだけじゃない?それで、ウェブサイトがブラウザにzoommtg://リンクを渡すと、ブラウザがzoomを開く感じ?Jupyter Notebooksみたいなのは、クロスオリジンリクエストをしてないから影響を受けないと思う。それに、コマンドラインツールがoauth2でログインさせてlocalhostのURLに戻すのも、単なるリダイレクトだから、クロスオリジンリクエストじゃないし、許可されるべきだよね?

公共のウェブサイトで使われることを意図したローカルにインストールされたソフトウェアは、プル方式で動作する場合、ローカルホスト上でHTTPサーバーを実行する必要があります。プッシュ方式ではない場合、そのサーバーは不要になります。ボーナスとして、そうすれば他人のローカルネットワークを無遠慮に探るウェブサイトがなくなります(うわっ)。

ローカルアプリとの通信方法が完全になくなるとしたら、それは素晴らしいことだと思う。なぜなら、それは非常に一般的なセキュリティの脆弱性の原因になっているから。

一見するとこれ、いい感じだね。ランダムなウェブサイトが任意のローカルIP(他のIPでも)にHTTPリクエストを送るなんて、頭おかしいよ。企業のアプリや統合が壊れても気にしないけど、企業は管理ツールを使ってこの「機能」を再有効化できるし、普通のユーザーも自分で設定できるように、「このウェブサイトはローカルデバイスを制御したいです - 許可/拒否」ってポップアップを表示すればいいだけ。

これはチェスタートンのフェンスの完璧な例だね。 > 企業のアプリや統合が壊れても気にしない どんなウェブブラウザのコードにも近づかないでほしい。

普通のユーザーは自分で設定できるはずだよ。「このウェブサイトはローカルデバイスを制御したいです - 許可/拒否」ってポップアップを表示すればいい。MacOSは今、これをアプリごとにやってるけど、ほとんどのユーザーは考えずに「はい」をクリックしちゃう。サイトごとにやるとちょっと不安になるかもしれないけど、そんなに大きな違いはないと思う。

これは誤解だね。ローカルネットワークデバイスはCORSによってランダムなウェブサイトから守られてるし、もう何年もそうだよ。完璧ではないけど、一般的にはかなり効果的。問題は、CORSがアクセスをターゲットサーバーの同意に基づいて制限していること。サーバーはウェブサイトからのリクエストを受け入れるためのヘッダーを返さなきゃいけない。この提案はそれを厳しくしようとしているんだ。ウェブサイトとネットワークデバイスが両方とも通信したい場合でも、ユーザーの許可が明示的に求められるように。歴史的には、サーバーとウェブサイトの合意が十分だと思ってたけど、最近のFacebookのトリックで、ウェブサイトが密かにスマホのアプリと話してたことがその仮定を壊しちゃった。ウェブサイトがローカルネットワークサーバーと結託して、ユーザーの利益に反することもあるからね。

インターネットエクスプローラーは、ゾーニングシステムでこれを解決したんだよね?

皮肉なことに、ChromeはWindows上でIEのセキュリティゾーンを部分的にサポートして利用してたけど、あんまりドキュメントがなかったね。

正直、現代の同等のものが存在すると思ってた。それがないなんて、馬鹿げてる。ローカルネットワークはカメラやマイクと同じように特別な許可が必要だと思う。

uBlock / uMatrixはデフォルトでこれをやってると思う。Paypalみたいなサイトが127.0.0.1を探ろうとしてるのをよく見るよ。私の「セキュリティ」のためにね、確かに…

私のuBlockのインスタンスではデフォルトで有効になってないみたい。特定のフィルターリストを使ってこれを実装してるみたいで、そのフィルターがチェックされてなかった。なんでかは全然わからないけど。そのフィルターリストの内容はここにあるよ [1]; 特定のサービスには例外があるから、有効にする前に例外をよく読んでね。[0] フィルターリスト -> プライバシー -> LANへの外部侵入をブロック [1] https://github.com/uBlockOrigin/uAssets/blob/master/filters/...>

これで、ローカル接続をする必要のない多くのウェブサイトをブロックできるけど、まだ粗い感じだね。こういう権限が必要なウェブサイトは、ほとんどが一つのローカルサーバーにアクセスするだけなんだ。全部にアクセスを許可するのは、最小権限の原則に反するよ。大多数のユーザーは、localhostやローカルネットワークで何が動いているか知らないから、リスクを理解できないんだよね。

包括的な実装はファイアウォールになるだろうね。どのCIDR、どのポートとか。こういうファイアウォールを構築するためのAPIがあればいいのに、例えばブラウザ拡張の一部として。でも、特定の機械(例えばルーター)やLAN、VPNにアクセスを与えるためのシンプルなデフォルトUIも欲しいな。ルーティングテーブルに基づいて、一般的な「プライベートネットワーク」にもアクセスできるように。localhostへのアクセスも別にね。サイトはこれらのカテゴリの一つを明示的に要求できるといいな。

大多数のユーザーは、localhostやローカルネットワークで何が動いているか知らないから、リスクを理解できないんだよね。そうそう、だからブラウザが「このサイトにhttp://localhost:3146にアクセスさせるか、http://localhost:8089にアクセスさせるか」って聞いても理解できないんだよね。理にかなった許可メッセージ(「このサイトがローカルネットワークのリソースにアクセスするのを許可しますか」)の方が、技術的な難しい言葉よりずっといいよ。混乱して「はい」をクリックしちゃうだけだから。

これ、rcloneのoauthメカニズムを壊す可能性があるんだ。リダイレクトURLをlocalhostに設定するから、oauthが終わるとrclone(自分のコンピュータで動いてるやつ)が呼ばれるんだよね。もし権限のダイアログがちゃんとした文言なら、ユーザーは許可すると思う。これは多分、妥当な提案だと思うけど、依存しているものが壊れるのは確実だね。

IIUC(私の理解が正しければ)、これでリダイレクトが壊れることはないはず。影響を受けるのは、(1) fetch/xmlhttprequests、(2) ページにリンクされていて、かつ読み込まれるリソース(画像、JS、CSSなど)。別のコメントでも指摘されているように、サーバーが適切なCORSヘッダーを提供しない限り、ブラウザがそのコンテキストでコンテンツを読み込むことはできない。だから、リクエストが成功するためには、サーバーがオープンであるか(cors: *)、リクエストコードと協力している必要がある(cors: website.co)。この変更は、ユーザーの承認なしに通信を防ぐものです。

これがウェブブラウザのデフォルトの挙動だなんて、信じられない。公共のウェブサイトがあなたのファイルシステム全体に静かにアクセスできるなんて、ありえないセキュリティホールだよね。でも、ローカルネットワークのサービスはXHRの対象として公平に扱われていて、セキュリティはサーバー自身に任されている。もしあなたが開発者で、会社のウェブアプリをテストのために開発マシンで動かしているなら(セキュリティのデフォルトが緩いか、まったくない場合)、facebook.comやgoogle.com、あるいは他の誰かが今アクセスしているかもしれない。自宅のネットワークで認証なしでデプロイすることを考えてみて。ルーターのファイアウォールを信頼しているからって、みんなが正しいCORS設定を持っているわけじゃないよね?

IPv6に問題があるんじゃないかと心配してる。誰か、IPv6がサイトローカルかどうかを判断する方法が実際にあるか教えてくれない?もしないなら、その提案はIPv6専用ネットワークで問題が出ると思う。過去にこの問題で苦労したことがある。私のIoTアプリケーションのウェブサーバーは、非ローカルアドレスからのリクエストを拒否したいんだ。IPv6のローカルアドレスを区別する方法が見つからなかったので、IPv6リクエストをローカルのIPv4アドレスにリダイレクトすることにした。それで終わりだった。自分の理解が正しいと確認できれば、もっと懸念を提起できると思う。つまり、アプリケーションがIPv6アドレスがリンクローカルかサイトローカルかを判断する実用的な方法がないということ。IPv6の「リンクローカル」アドレスを試してみたけど、これは一般的なアプリケーションではなく、ルーター用のもののようで、通常のアプリケーション使用には合わないみたい。 .localアドレスをローカルサーバーとして含めることで少し余地はあるけど、.localドメインの実装は現在、さまざまなOSで一貫性がないように見える。例えば、Raspberry PI OSは「some_address」のmDNS解決はするけど、「someaddress.local」はしない。Ubuntu 24.04は「someaddress.local」を解決するけど、「someaddress」は解決しない。そして、どちらも「someaddress.local」は解決しない(これは一時期推奨されていたと思うけど、今は非推奨で機能しない)。これは提起する価値のある問題のように思える。そして、ローカルネットワークアドレスに対してプライベートに発行された証明書の使用を誰も許可しないのが本当にイライラする。「ローカルアドレスにHTTPSなし」っていうのは直さなきゃいけない。

誰か、インバウンドのIPv6アドレスが「ローカル」であるかどうかを判断する方法があるか教えてくれない? いいえ、それはIPv6の反対で、グローバルにルーティング可能であるべきものだから。その概念は存在するべきではない。さらに、Googleですら「ローカル」の意味について合意できていない - 記事によれば、彼らはこのゴミを考える過程で「ローカル」の意味を「プライベート」の再定義に完全に変更したそうだ。CIDRサブネットに基づいて非標準の恣意的なセキュリティ境界をHTTP拡張として作るのは完全にクレイジーだ。あなたのアプリケーションについて言えば、やり方が全然違う。アプリケーションは公開されていると仮定して、その前提でセキュリティを設計すべきだ。多くのアプリケーションがこの間違いを犯して、「ローカル専用」アプリケーションにサルーンドアのセキュリティを設計して、ここで話題になっているような過剰反応を引き起こしている。「.local」はmDNS用に予約されていて、RFCにも記載されているけど、これは頻繁に無視されている。

そもそもこれは可能であってはいけない。正当な理由はない。ユーザーに「同意」を与えさせるのは、ただそれをもっと許可するための手段であって、止めるためのものではない。

確かに正当な理由はあるよね。例えば、ブラウザベースのCADシステムが3Dマウスと通信する場合とか。あとは、ウェブサイトがインストールされたアプリに認証情報を渡して、ブラウザベースのSSOやパスワードマネージャーを使ってログインできるようにする場合とかね。