Skip to content

[security] Remove file:// protocol from Web Surfer URL allow-list (local file read)#7942

Open
AUTHENSOR wants to merge 2 commits into
microsoft:mainfrom
AUTHENSOR:redthread/remove-file-protocol-b841a05d04
Open

[security] Remove file:// protocol from Web Surfer URL allow-list (local file read)#7942
AUTHENSOR wants to merge 2 commits into
microsoft:mainfrom
AUTHENSOR:redthread/remove-file-protocol-b841a05d04

Conversation

@AUTHENSOR

Copy link
Copy Markdown

Summary

The MultimodalWebSurfer accepts file:// as a valid URL protocol (line 655). This allows the LLM to navigate to local files (file:///etc/passwd, file:///home/user/.ssh/id_rsa, etc.), which Playwright renders in the page. The agent then reads the page content and sends it back to the LLM — local file read via the web browsing agent.

Severity: HIGH
Class: Local file read via file:// protocol acceptance

Root cause

_multimodal_web_surfer.py:655:

if url.startswith(("https://", "http://", "file://", "about:")):

file:// is in the allowed protocol list. visit_page passes it directly to page.goto(url).

Exploit chain

  1. LLM generates: {"name": "visit_url", "args": {"url": "file:///etc/passwd"}}
  2. Web Surfer navigates to file:///etc/passwd (accepted because file:// is allowed)
  3. Playwright renders the file content in the page
  4. Web Surfer reads the page content and includes it in the next LLM message
  5. LLM now has the contents of /etc/passwd — or any local file

Fix

Remove file:// from the allowed protocol list. A web-browsing agent should only navigate to web protocols (https://, http://). The about: protocol is kept for blank pages.

Verification

  • Single-line change: remove "file://" from the protocol tuple
  • ruff check: clean
  • The about: protocol is preserved for blank-page navigation

Dedup

Searched issues for "file://", "local file read", "web surfer security". Zero matches. Issue #7457 is about indirect prompt injection via page title (different surface). Novel.


Generated by redthread. Single-purpose security fix.

John Kearney added 2 commits July 9, 2026 18:34
LocalCommandLineCodeExecutor docstring claimed 'Command line code is
sanitized using regular expression match against a list of dangerous commands'
but no such sanitization exists in the execution path. The only processing
is silence_pip (pip output suppression). An operator reading the docstring
would believe destructive commands are filtered when they are not.

Replace the false claim with a clear warning that no sanitization is performed
and Docker-based executors should be used for untrusted code.
The MultimodalWebSurfer accepted file:// as a valid URL protocol, allowing
the LLM to navigate to local files (file:///etc/passwd). The file content
gets rendered in the page and sent back to the LLM — local file read.

@ErenAta16 ErenAta16 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Confirmed on main: line 655 of _multimodal_web_surfer.py has file:// sitting right in the allowed-protocol tuple next to https:///http://, and visit_page passes the URL straight to page.goto() with no further check. Given the agent then reads back and forwards whatever Playwright renders, that is a real local-file-read path once file:// is reachable at all, not just a theoretical one. Scope of the fix (removing the one protocol from the allow-list, touching two files) looks correctly minimal — it does not try to also solve command sanitization, which is the separate, correctly-scoped #7941.

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.

2 participants