TAB-1104: gate agent navigation + Tabstack URL tools through the action firewall#595
Merged
srbiv merged 2 commits intoJul 17, 2026
Conversation
goto was the only action tool that skipped the firewall, so a prompt-injected page could exfiltrate caller task/data secrets by having the agent navigate to an attacker URL with the secret in the query string — no form, no approval. Add assessNavigation, which allows a goto only to a caller-named host (start host + trusted_hostnames) or under unsafe_mode, mirroring the fill/submit gates. Blocks return a recoverable error and emit a firewall event.
…AB-1104) The Tabstack extract/generate tools fetch a model-supplied URL — an identical data-egress sink to goto — but bypassed the firewall. Apply the same destination allowlist (assessNavigation: caller start host + trusted_hostnames, unsafe_mode bypass) to all three tools, and extract the shared remediation builder so every gated sink emits identical guidance.
lmorchard
approved these changes
Jul 17, 2026
lmorchard
left a comment
Collaborator
There was a problem hiding this comment.
LGTM and works for me, +1 assuming evals don't tank for some reason
srbiv
deleted the
stafford/tab-1104-goto-navigation-is-an-ungated-data-exfiltration-sink-ipi
branch
July 17, 2026 20:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The action firewall (TAB-976) gates form fill/submit but not URL egress.
gotoand the Tabstack extract/generate tools each take a model-controlled URL and send it out, so an injected page can exfiltrate the caller 's task/data secrets to an attacker host — no form, no approval.Change
assessNavigation(targetUrl, firewall): allow only a host the caller named (start host viawithTrustedStartHost+trusted_hostnames), or whenunsafe_modeis set. Non-http(s) targets (null host) are blocked (fail closed).gotoandtabstack_extract_markdown/tabstack_extract_json/tabstack_generate_jsonwith it. Blocks return a recoverable error and emitFIREWALL_BLOCKED_NON_INTERACTIVE(kindnavigation).buildFirewallRemediationsso every gated sink emits identical guidance.Gating the destination host, not the URL contents, is deliberate: scanning the URL for the secret is a blocklist (encoding/param/method evade it). Denying the destination is independent of payload shape.
Scope / severity
Prod's remote browser currently confines navigation to the start domain (BrightData
navigate_domains_limit), so cross-domain exfil is not exploitable end-to-end today — but that is a third-party config, not a control we own. This makes the boundary explicit and portable (local browsers, other zones, future config changes). Not a P1 bleed; a real hardening.Tradeoff
Blocks the agent from following a link/search result to a host the caller did not name. Opt in via
trusted_hostnames(exposed on /v1/automate, TAB-980) orunsafe_mode— same escape hatch as fill/submit.Testing
assessNavigationunit tests (trusted/untrusted/unsafe/null-host/case).gototool: blocks untrusted (no navigation, emits event), allows trusted + unsafe.