Fix: extend cross-origin-frame-redact to <object> and <embed>#208
Conversation
…e[srcdoc] Closes red-team audit items #9 and #11 from #203. The rule previously only covered <iframe src=…> with a cross-origin http(s) URL; this broadens it to cover the same agent-side threat carried by: - cross-origin <object data=…> and <embed src=…> (same SOP-bypass shape as a cross-origin iframe), and - iframe[srcdoc] regardless of origin — the inline HTML body wasn't authored as part of the host page, so an agent walking the DOM can still ingest external content even though srcdoc inherits the embedding origin. srcdoc takes precedence over src per spec, so a srcdoc iframe with a cross-origin src is redacted via the srcdoc (inline) branch — the placeholder reflects inline content rather than a misleading cross-origin label. Popup label renamed from "Hide Cross-Origin Frames" to "Hide Embedded Frames" to reflect the broader coverage. Rule ID is unchanged so user settings carry over. Adds a fast-check property test for the iframe/object/embed boundary per the repo convention. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
1 issue found.
About Unblocked
Unblocked has been set up to automatically review your team's pull requests to identify genuine bugs and issues.
📖 Documentation — Learn more in our docs.
💬 Ask questions — Mention @unblocked to request a review or summary, or ask follow-up questions.
👍 Give feedback — React to comments with 👍 or 👎 to help us improve.
⚙️ Customize — Adjust settings in your preferences.
| label: "Hide Embedded Frames (Experimental)", | ||
| description: | ||
| "Remove cross-origin iframes from the page and replace them with a click-to-reveal placeholder, so browser-use agents don't ingest embedded-origin content unless the user opts in.", | ||
| "Remove cross-origin iframes, <object>/<embed> resources, and srcdoc iframes from the page and replace them with a click-to-reveal placeholder, so browser-use agents don't ingest embedded content unless the user opts in.", |
There was a problem hiding this comment.
skills/agent-browser-shield-config/SKILL.md (lines 109–115) currently states:
cross-origin-frame-redact— Replace cross-origin<iframe>elements with click-to-reveal placeholders … Same-origin frames,srcdocframes, and inert (about:/javascript:/data:/blob:) frames are left alone.
After this PR, that description is factually wrong in two ways:
srcdociframes are now redacted, not "left alone."- Cross-origin
<object data=…>and<embed src=…>are also redacted but aren't mentioned.
Since this change alters what agents encounter on the page (new placeholders they didn't see before), both skills/agent-browser-shield-config/SKILL.md and skills/agent-browser-shield/SKILL.md should be updated to match the new behavior described here.
Based on AGENTS.md and CONTRIBUTING.md
There was a problem hiding this comment.
Fixed in bb45b9d — updated skills/agent-browser-shield-config/SKILL.md to describe the broadened scope (cross-origin <iframe src>, cross-origin <object data>/<embed src>, and <iframe srcdoc> regardless of origin).
One note on the other file: skills/agent-browser-shield/SKILL.md doesn't currently mention this rule by name (rule descriptions live in agent-browser-shield-config and in docs/src/content/docs/rules.md, both of which are now consistent), so no edit needed there.
— Claude Code, on behalf of @twschiller
…dened rule Exercises the two new branches of cross-origin-frame-redact added in this PR: - "From the brand" section embeds an <iframe srcdoc=…> whose inline HTML carries an AGENT NOTE payload. srcdoc inherits the host origin, so it isn't a SOP bypass, but the body lands in the DOM as content an agent can ingest. With the extension off the brand copy + agent note render; with it on, the rule replaces the whole iframe with a placeholder. - "Spec sheet" section embeds a cross-origin <object data=https://specs.…>. The synthetic CDN doesn't resolve, so the browser falls back to the <object>'s children — also an instruction-shaped payload. The rule redacts the entire <object>, fallback included. Updates the demo README's per-page rule table to list cross-origin-frame-redact on the product detail row alongside social-embed-redact. Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
Update agent-browser-shield-config SKILL.md to reflect the broadened cross-origin-frame-redact behavior: srcdoc iframes are now redacted (not left alone), and cross-origin <object>/<embed> are covered too. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…igin_as_fallback srcdoc inherits the embedding origin so isn't the Roesner SOP-bypass threat, and the manifest's `match_origin_as_fallback: true` setting means every rule already runs inside the srcdoc frame on its own. Redacting the whole iframe from the parent treats authored-by-the-page content as if it were untrusted cross-context. Keeps the object/embed extension (item #9) — those carry the same SOP-bypass shape as a cross-origin iframe when their data/src loads a cross-origin resource. Reverts the popup label rename back to "Hide Cross-Origin Frames (Experimental)" since srcdoc is no longer covered. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Summary
Addresses red-team audit item #9 from #203. The rule previously covered only
<iframe src=…>with a cross-origin http(s) URL; this PR adds<object data=…>and<embed src=…>to the selector when they load a cross-origin resource. Same SOP-bypass shape per Roesner & Kohlbrenner — the browser composites the embedded document into the parent's render/a11y tree, so an agent that ingests the parent page ingests the cross-origin payload alongside it.Item #11 (
<iframe srcdoc>) declinedOriginally bundled into this PR; dropped after review.
srcdocinherits the embedding origin (no SOP crossing), andextension/src/manifest.json:37setsmatch_origin_as_fallback: true— the content script runs inside thesrcdocframe so every other rule already applies to its body. Redacting the whole frame would treat parent-authored inline HTML as untrusted cross-context content, which is a different threat model than the Roesner motivation the rule was built around. If we want a defense for inlinesrcdocpayloads later it should be a separate rule with its own motivation; for now the audit item is being declined.Notable choices
Hide Cross-Origin Frames (Experimental)still describes the scope.cross-origin-frame-redact) — existing user settings carry over.<iframe src>:Cross-origin frame from {origin}(unchanged).<object data>/<embed src>:Cross-origin embedded object from {origin}— surface the origin so the user can decide whether to reveal./product/:idgains a cross-origin<object>spec sheet whose fallback DOM is instruction-shaped, so the before/after view exercises the new branch.Test plan
npx jest src/rules/__tests__/cross-origin-frame-redact*— 31 tests pass (19 existing in*.test.ts→ 25 with 6 new for<object>/<embed>, plus 6 new property cases in*.property.test.ts).npx jest— full extension suite (1673 tests) passes.bun run check— biome + eslint clean.pre-commit run --files docs/src/content/docs/rules.md demo-site/README.md skills/agent-browser-shield-config/SKILL.md— mdformat clean.iframe[src]/object[data]/embed[src]triggers a placeholder; same-origin URLs and inert protocols (about:/javascript:/data:/blob:) pass through;iframe[srcdoc]is always left alone regardless of accompanyingsrc.🤖 Generated with Claude Code