browse-mcp arbitrary file write via unconfined download/state paths, reachable through indirect prompt injection
Undisclosed·browse-mcp (Playwright-based headless-browser MCP server)Fixed
browse-mcp's browser_download tool wrote a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, and browser_save_state/browser_load_state honored an explicit path unchanged, so a malicious MCP client or an agent steered by indirect prompt injection on a visited page could choose an arbitrary save_dir/path plus a URL whose response body became the file contents, writing attacker-controlled bytes to any path the process could reach (e.g. ~/.bashrc, an autostart entry, or a cron file); a force_fetch fallback also used a raw fetch() that bypassed the BROWSE_MCP_ALLOWED_ORIGINS origin fence.
- Blast radius
- Arbitrary file write with potential host code execution on any machine running an unpatched browse-mcp server (<=0.8.1); no specific victim organisation or exploitation-in-the-wild was disclosed in the advisory.
- Root cause
- MCP tool arguments (save_dir/path for downloads and state files) were passed straight into filesystem join/write calls with no path confinement or traversal checks, and a fallback fetch path bypassed the configured origin allowlist entirely.
- How it was caught
- Found and privately reported by a security researcher (credited as 'novice-22') rather than caught in production use.
- What changed
- Fixed in browse-mcp 0.8.2: save_dir is confined under ~/.browse-mcp/downloads and explicit state paths under ~/.browse-mcp/state, with absolute paths and '..' escapes rejected; the advisory notes that hiding tools via an allowlist does not stop a malicious MCP client from calling them by name, so upgrading is the actual fix.
Take-awayNever let an agent-facing tool pass caller-supplied paths straight into filesystem writes — canonicalize and confine every save/load path to a fixed root before use, and don't rely on an origin/tool allowlist as a substitute for real input validation.