Skip to content

fix(scene): browser sources request only what their pages load - #90

Merged
kixelated merged 5 commits into
mainfrom
quest/m0/browser-offline
Nov 7, 2026
Merged

kixelated merged 5 commits into
mainfrom
quest/m0/browser-offline

Conversation

@kixelated

@kixelated kixelated commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Problem

quest/m0/browser-offline.md, from the follow-ups of moq-dev/studio#78: the CEF browser helper contacts Google on its own, a privacy leak and a network dependency nobody asked for. Routed through a test proxy, a fresh helper on main showing one loopback page with a text field asks for:

Request Source (Chromium 156 / CEF 156.0.15)
clients2.google.com/time/1/current network time (NetworkTimeServiceQuerying)
update.googleapis.com/service/update2/json an on-demand install of the on-device AI model's manifest (app ceofaddefefcbblgcgnibnonglccbfja, optimization_guide_on_device_model_installer.cc)
redirector.gvt1.com/edgedl/chrome/dict/en-us-10-2.bdic the spellcheck dictionary
www.google.com/async/folae AI Mode eligibility (AimEnabled)
content-autofill.googleapis.com/v1/pages/... autofill field predictions for the page's form, retried with backoff (AutofillServerCommunication)

The switches the quest suggested do not stop them in CEF 156. With --disable-background-networking, --disable-component-update, and --disable-spell-checking, all five still went out: the manifest installer requests itself regardless of --disable-component-update, and --disable-spell-checking no longer exists in CEF.

Approach

All in rs/moq-scene/src/browser/host.rs; the switches stay in on_before_command_line_processing, beside --no-sandbox.

  • --disable-features=NetworkTimeServiceQuerying,AutofillServerCommunication,AimEnabled, appended to the list CEF already passes (GlicActorUi,AutofillActorMode,LensOverlay,KillOnInvalidNavigationHeaders) rather than replacing it.
  • --component-updater=url-source=data:: the component updater's server is a URL the network stack never contacts, so no component installs or updates, including installers that ask on their own.
  • After initialize, before any page opens, the profile's spellcheck.dictionaries is set to an empty list, so Chromium fetches no dictionary. No switch does this. Failing to set it fails the helper, saying why, rather than leaking.
  • New test the_helper_requests_only_its_pages in rs/moq-studio/tests/browser.rs: the helper runs through a wrapper script that adds --proxy-server pointing at a listener in the test, which records the first line of every connection. Chromium sends loopback past a proxy, so the served page still loads. It shows a page with a text field, waits for it to draw plus 2 s, and asserts nothing reached the proxy. Studio::start takes the helper program, so the wrapper can stand in for it.

Each knob was confirmed by leaving it out alone: each brought back exactly the requests the table above attributes to it. spellcheck.dictionaries is the pref that matters; browser.enable_spellchecking = false alone still fetched the dictionary.

Impact

  • Browser sources no longer contact Google in the background: no network time, component installs, spellcheck dictionary, AI Mode check, or autofill predictions. Pages still load whatever they load themselves.
  • Pages are not spellchecked. The profile keeps an empty dictionary list once a new helper starts on it. README says so.
  • Autofill can no longer use Google's server-side field predictions. Local autofill is unaffected.
  • Public API: none (host.rs is private to the helper). Wire: none. The helper protocol is unchanged.

Choices made without asking

  • --component-updater=url-source=data: rather than --disable-component-update. The latter left the manifest install, so it is not used at all: pointing the updater nowhere covers every component, including installers that bypass --disable-component-update. Chromium documents the --component-updater values as debug options, so a CEF bump could drop it; the new test would then fail in the nightly.
  • No --disable-background-networking. Leaving it out changed nothing the test sees, so it was dropped rather than kept on faith.
  • Settle time of 2 s after the page draws. Across 6 runs on main, every request's first attempt came before the page drew (from 1.7 s before to 0.04 s before); only autofill's retries came later.

Alternatives

  • --optimization-guide-manifest-override=<file> would stop only the AI model manifest, and needs a config file written somewhere.
  • Chrome policies (ComponentUpdatesEnabled, SpellcheckEnabled, BrowserNetworkTimeQueriesEnabled) through CEF's chrome_policy_id need a managed policy directory on disk. --policy= on the command line had no effect. The component_updates.component_updates_enabled local-state pref still sends the update check, marked "updatedisabled": true.
  • Reading a NetLog (--log-net-log) in the test instead of a proxy would also catch raw DNS, but needs JSON parsing and a dependency; the proxy is shorter and states its result directly.

Validation

All on nixos (RTX 3070 Ti, GNOME), over ssh. CPU path: no display, Mesa lavapipe, as just render-sw sets it. GPU paths through the logged-in session (X11 with DISPLAY=:0 and its Xwayland auth; Wayland with WAYLAND_DISPLAY=wayland-0).

Head Check Result
main's host.rs with the new test the_helper_requests_only_its_pages, CPU, --stress-count 5 plus one run fails 6/6, listing the five hosts above
73ceb71 + the formatting fix (= d3e8b81) the_helper_requests_only_its_pages, CPU, --stress-count 10 10/10
d3e8b81 quest gate just ci pass, 279 tests
d3e8b81 quest gate just render-sw 49 + 6 + 14 + 1 pass, browser suite 14/14
d3e8b81 browser suite, X11 GPU 14/14
d3e8b81 browser suite, Wayland GPU 14/14

quest check on macOS: pass.

Follow-ups

  • None needed. A future CEF bump that adds a background request fails the new test in the nightly.

Review

  • Reviewer: Codex (quest review --base origin/main), gpt-6.1-sol, medium effort.
  • Round 1, at d3e8b81: no findings.
  • Reviewed head: d3e8b81.
  • Head c37a48f adds only a merge of origin/main at 79c60b9 (#89, #85, #88). Its only conflict was the quest/m0/README.md link list, which quest resolved; the changed lines of git diff origin/main...c37a48f match those of git diff f760ee7...d3e8b81 exactly, so the review above covers it. quest gate just ci passes on c37a48f on nixos (281 tests).

(Written by Claude Opus 5.5)

🤖 Generated with Claude Code

@pullfrog

pullfrog Bot commented Nov 7, 2026

Copy link
Copy Markdown

Pullfrog  | Review this ➔

kixelated and others added 2 commits November 7, 2026 06:45
The CEF helper asked Google, unprompted, for the network time, component
updates (the on-device AI model's manifest), a spellcheck dictionary, AI
Mode eligibility, and autofill predictions for each form. It now disables
NetworkTimeServiceQuerying, AutofillServerCommunication, and AimEnabled
(joined to CEF's own disabled features), points the component updater at
no server, and lists no spellcheck dictionaries. The browser suite routes
the helper through a proxy that fails the test on any request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Browser sources make no outside requests fix(scene): browser sources request only what their pages load Nov 7, 2026
@kixelated
kixelated marked this pull request as ready for review November 7, 2026 15:01
@coderabbitai

coderabbitai Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: cd8d0b8e-3618-4c8a-8cec-7697247d600e
Commits

Reviewing files that changed from the base of the PR and between 3e07182 and e6a7c73.

Files selected for processing: 5

  • README.md
  • quest/m0/README.md
  • quest/m0/browser-offline.md
  • rs/moq-scene/src/browser/host.rs
  • rs/moq-studio/tests/browser.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@kixelated kixelated left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed head d3e8b81f0193808013e4a427098a6480f60ef45e against base f760ee7227519ff79983bb5c5c95b3c1e7db529c.

No actionable findings. The disabled-feature list preserves CEF's existing entries, and the pinned Chromium sources gate the identified time, autofill and AI eligibility requests. The component updater uses the URL override for both updates and pings. Spellcheck configuration is applied before queued pages open, with preference-setting failure terminating the helper. The regression test starts its proxy before the helper, preserves helper arguments through the wrapper, requires the page to render, and stops the helper before asserting.

Direction: keep the targeted configuration and the startup-network regression test. Its proxy observation is a useful guard for the reported HTTP/HTTPS requests, not proof that every protocol or later background activity is absent.

Verification limits: GitHub-only static review of the changes, helper lifecycle/test wiring, and relevant CEF/Chromium sources at the versions pinned by the flake. I read the pinned quest context as source but did not execute quest context, builds, tests, packet capture or the reported ablation/stress runs. No independent runtime or exhaustive network-privacy verification. COMMENT only, not approval.

(Written by review (OpenAI))

@kixelated

Copy link
Copy Markdown
Contributor Author

Pick (/quest-complete, maintainer away under /afk, recommended option): ✅ Merge, keeping the choices made without asking: url-source=data:, which the test guards if a future CEF drops it, and the test's 2 s quiet window after the page draws, a negative check that needs a window. Codex and the OpenAI review found nothing. Merged main (#91, #92), with no conflicts.

(Written by Claude Opus 5.5)

@kixelated
kixelated merged commit 73c2c7b into main Nov 7, 2026
3 checks passed
@kixelated
kixelated deleted the quest/m0/browser-offline branch November 7, 2026 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant