Summary
The browser tool family (#94, PR #260) stores per-page interaction state — element references, generation counter, and helpers (window.__forge_els, window.__forge_gen, window.__forge_center, window.__forge_protected, window.__forge_select_*) — in the page's main JavaScript world (forge-cli/tools/browser/snapshot.js). The digest returned to the LLM is therefore page-controlled content, and a hostile page can:
- Spoof digests — feed the LLM attacker-controlled "observations" attributed to tooling (a prompt-injection amplifier). This is the real risk.
- Clobber/freeze the
window.__forge_* helpers to break the tools (accidental for a merely-defensive page, deliberate for a hostile one).
- Defeat the live-DOM sensitive-fill re-check (low value — the page receives typed text regardless).
The code already documents this as a trust boundary (see the header comment in snapshot.js), and clicks/fills dispatch by coordinate through trusted CDP input, so a hostile page cannot by itself make the browser act outside the page. But digest spoofing remains.
Proposed fix
Evaluate snapshot.js (and the interaction helpers) in an isolated world via CDP Page.createIsolatedWorld (chromedp's isolated-context evaluation). Element references can live in the isolated world while clicks still dispatch by coordinate through trusted CDP input, so the page cannot spoof the digest or clobber the helpers.
Context
Tracked as the follow-up the snapshot.js trust-boundary comment references. Raised in the PR #260 re-review. Non-blocking for #260 (documented in the meantime), but filing so the code comment is accurate.
Summary
The browser tool family (#94, PR #260) stores per-page interaction state — element references, generation counter, and helpers (
window.__forge_els,window.__forge_gen,window.__forge_center,window.__forge_protected,window.__forge_select_*) — in the page's main JavaScript world (forge-cli/tools/browser/snapshot.js). The digest returned to the LLM is therefore page-controlled content, and a hostile page can:window.__forge_*helpers to break the tools (accidental for a merely-defensive page, deliberate for a hostile one).The code already documents this as a trust boundary (see the header comment in
snapshot.js), and clicks/fills dispatch by coordinate through trusted CDP input, so a hostile page cannot by itself make the browser act outside the page. But digest spoofing remains.Proposed fix
Evaluate
snapshot.js(and the interaction helpers) in an isolated world via CDPPage.createIsolatedWorld(chromedp's isolated-context evaluation). Element references can live in the isolated world while clicks still dispatch by coordinate through trusted CDP input, so the page cannot spoof the digest or clobber the helpers.Context
Tracked as the follow-up the
snapshot.jstrust-boundary comment references. Raised in the PR #260 re-review. Non-blocking for #260 (documented in the meantime), but filing so the code comment is accurate.