Dev Study
← ブラウザの仕組み
レッスン 2 / 6·約 9 分·第5期 ブラウザの仕組み

分離の単位は origin ではなく site — 妥協が設計に残っている

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力今ここ
  2. DNS名前→IP
  3. ルータ経路選択
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理
  7. DB保存

前回、プロセスを分けて特権を取り上げる仕組みを見ました。今回は「では何を単位に分けるのか」を扱います。ここに、互換性のための妥協がそのまま残っています。

まず結論

「ブラウザはオリジンごとにプロセスを分けている」という説明は**誤り**です。分離の単位は **site** で、site とは **scheme + eTLD+1**。`https://foo.example.com:8080` の site は `https://example.com` です。サブドメインもポートも無視されます。

なぜ origin にしなかったのか。理由は公式に明記されています——`document.domain` を書き換えて別オリジン同士が行き来している既存ページを壊さないためです。そして公式は、これを **Limitations(限界)の節に自分で書いています**。

? 読む前に予測

Chromium の Site Isolation で、`https://foo.example.com:8080` と `https://bar.example.com` は同じプロセスに入りうるでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

「オリジンごと」と言った時点で誤り

前回、プロセスを分けて特権を取り上げる話をしました。残っているのは何を単位に分けるかです。

ここで多くの説明が「オリジンごと」と書きます。これは誤りです。 公式の定義はこうです。

Here, we use a precise definition for a site: the scheme and registered domain name, including the public suffix, but ignoring subdomains, port, or path. For example, an origin like https://foo.example.com:8080 would have a site of https://example.com.

別の文書では、もっと短く書かれています。

Sites are defined as scheme plus eTLD+1

同じURLを origin と site で見る(公式の例そのもの)表
URL https://foo.example.com:8080
origin https://foo.example.com:8080
site (scheme + eTLD+1) https://example.com
無視されるもの サブドメイン(foo)・ポート(8080)・パス

site の方が粗いのです。 だから https://foo.example.com と https://bar.example.com は、オリジンとしては別なのに、site としては同じ。同じプロセスに入りえます。

具体実物

なぜ粗い方を選んだのか

細かく分ける方が安全なのに、なぜ粗い site を選んだのか。理由は隠されていません。

We use sites instead of origins to avoid breaking compatibility with existing web pages that might modify their document.domain to communicate across multiple subdomains of a site.

document.domain を書き換えると、同じサイト内の別オリジン同士が互いに触れるようになります。そういうページが既に世の中に存在している。プロセスをオリジン単位で分けてしまうと、それらが動かなくなります。

since different origins within a given site may have synchronous access to each other if they each modify their document.domain

つまりこうです。技術的にはオリジンで分けたい。しかし既存のWebを壊せないので、site で妥協した。

ただし、これは書き換えが効く前提の話です。[PM] は現状について Origin-Agent-Cluster is now enabled by default, effectively disabling changes to document.domain unless an OAC opt-out header is used. と注記しています。現在の Chromium では、OAC をオプトアウトするヘッダが無いかぎり document.domain の書き換えは既定で無効です。

✓ ここまでの確認

公式が origin ではなく site を分離の単位に選んだ理由として明記しているものはどれですか。

具体実物

公式が、自分で「限界」と書いている

ここが今回いちばん大事な箇所です。この妥協は、都合よく説明されていません。公式 [SI] の Limitations という見出しの下に置かれています。

Sites vs Origins: Compatibility with document.domain changes currently requires us to use sites (e.g., https://example.com) rather than origins (e.g., https://foo.example.com) for defining process boundaries. This allows multiple origins within a site to share the same process.

“requires us to”(そうせざるを得ない)という言い方で、複数のオリジンが同じプロセスを共有してしまうことを結果として書いています。

[SI] に Goals という名前の節はありませんが、Overview・Motivation・Current Status のように「何をしているか」を書く節と、Limitations・Tradeoffs のように「届いていないもの」を書く節が並んでいます。前者だけを読むと、その仕組みは完璧に見えます。 何を諦めたかは Limitations にしか書かれていません。

✓ ここまでの確認

「サイトを単位にしたことで複数のオリジンが同じプロセスを共有する」という点について、公式はどう扱っていますか。

⇄ 2つを見比べる
具体例 A

分離の単位が origin でなく site

セキュリティだけを考えれば origin 単位で分けたいところです。しかし `document.domain` を書き換えて複数サブドメイン間で行き来している既存ページがあるため、それを壊さないよう粗い site を単位にしました。結果として、複数のオリジンが同じプロセスを共有します。公式はこれを Limitations に書いています。

理想と、実際に採られた形表
理想 origin 単位で分けたい
制約 document.domain を使う既存ページが壊れる
実際 site (scheme + eTLD+1) 単位
残るもの 複数originが同じプロセスを共有しうる
具体例 B

nginx の proxy_pass と末尾スラッシュ(第32週)

第32週で見たとおり、`proxy_pass` は末尾のスラッシュ1文字の有無で上流に渡るパスが変わります。整理された規則というより、2通りの書き方それぞれに別の意味が後から固定された形です。公式は、置換すべき部分を決められない場合には「URIを付けずに書け」と指示するに留めています。

第32週で見た形表
理想 書き方が1つに定まっていてほしい
制約 既存の設定ファイルの意味を変えられない
実際 末尾スラッシュの有無で挙動が分かれる
残るもの 1文字の差が宛先を変える

ブラウザの分離単位と、nginx の設定記法。まったく別の話ですが、なぜどちらも「きれいでない形」に落ち着いたのでしょうか。

どちらも、ゼロから設計されたものではありません。先に使われているものがありました。

具体実物

穴を塞ぐ側 — クロスサイトの iframe

site を単位にすると決めても、もう一つ問題があります。ページの中に別サイトの iframe があったらどうなるか。

かつてはこうでした。

At the time, cross-site subframes stayed in the same process as their parent frames.

親と同じプロセスに同居していたわけです。これでは「1プロセス=1サイト」が成立しません。そこで導入されたのが OOPIF です。

This page provides an overview of Chromium's support for out-of-process iframes (OOPIFs), which allow a child frame of a page to be rendered by a different process than its parent frame.

代償は小さくありませんでした。

Supporting OOPIFs required a large architecture change to Chromium. At a high level, the browser process now tracks subframes directly, and core parts of the browser (e.g., painting, input events, navigation, etc) have been updated to support OOPIFs. Many other features in Chromium now combine information from frames in multiple processes when operating on a page, such as Accessibility or Find-in-Page.

ページ内検索が複数プロセスにまたがる仕事になった、という一点で規模が想像できます。

この章のまとめ

  • 分離の単位は origin ではなく site。site = scheme + eTLD+1(サブドメイン・ポート・パスを無視)。
  • 公式の例: origin https://foo.example.com:8080 → site https://example.com。「オリジンごとに分離」は誤り。
  • origin にしなかった理由は明記されている。document.domain を書き換える既存ページを壊さないため。
  • 公式はこれを Limitations 節に置き、複数originが同じプロセスを共有しうると自認している。Overview だけ読むと完璧に見える。
  • クロスサイト iframe はかつて親と同じプロセスに同居していた。OOPIF がそれを別プロセスに出し、Find-in-Page や Accessibility が複数プロセスにまたがる仕事になった。
  • プロセス上限は "soft" で利用可能メモリから決まる。公式の「100」は例示であって既定値ではない。
  • メモリ増の 10-13% / 3-5% は、その版の測定値。現行値としては引けない。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 3正解: 0

「Site Isolation はオリジンごとにプロセスを分ける仕組みである」という説明の評価はどれですか。

用語集(4語)
site
公式の定義は “the scheme and registered domain name, including the public suffix, but ignoring subdomains, port, or path”。別の箇所では **scheme plus eTLD+1** とも書かれる。例: origin `https://foo.example.com:8080` → site `https://example.com`。
eTLD+1
public suffix(`.com` や `.co.jp` のような、誰でも登録できる階層)に、その1つ手前のラベルを足したもの。`example.com` や `example.co.jp` にあたる。site の定義に使われる。
Soft Process Limit
デスクトップで設けられる、**超過しうる**プロセス数の上限。値は “based on the memory available on a given client” で決まる。超えると同一サイトのプロセスをランダムに再利用し始める。Android にはこの上限が無く、OSのプロセス破棄に任せる。
OOPIF (Out-of-Process iframes)
子フレームを親フレームとは別のプロセスで描画できるようにする仕組み。公式の説明は “allow a child frame of a page to be rendered by a different process than its parent frame”。クロスサイト iframe があっても「1プロセス=1サイト」を保てるようにする。