{"id":"CVE-2026-55557","aliases":["EUVD-2026-65581","GHSA-m9mq-7m7q-xc6p"],"status":"published","title":"browse-mcp: Arbitrary file write via unconfined download and state paths","description":"browse-mcp is a Playwright-based headless-browser MCP server for MCP-capable agents. Prior to 0.8.2, browser_download writes a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, while browser_save_state and browser_load_state honor a caller-controlled path unchanged. A malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page, can choose an arbitrary save_dir or state path and a URL whose response body becomes attacker-controlled file contents, allowing writes to any path the process can reach, including ~/.bashrc, autostart entries, or cron files, and potentially leading to host code execution. The force_fetch fallback also uses a raw fetch() that bypasses the BROWSE_MCP_ALLOWED_ORIGINS origin fence. This issue is fixed in version 0.8.2.","severity":{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-10","score":0.00238,"percentile":0.14982,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-22"],"published":"2026-08-25T16:28:07Z","modified":"2026-10-28T02:30:28Z","fixes":[{"ecosystem":"npm","package":"browse-mcp","fixed_in":["0.8.2"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"browse-mcp","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"last_affected":"0.8.1"},{"fixed":"0.8.2"}]}]},{"source":"osv","ecosystem":"npm","package":"browse-mcp","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.8.2"}]}]}],"products":[{"vendor":"that1drifter","product":"browse-mcp"}],"references":[{"url":"https://github.com/That1Drifter/browse-mcp/security/advisories/GHSA-m9mq-7m7q-xc6p","tags":["x_refsource_CONFIRM","advisory","web"]},{"url":"https://github.com/That1Drifter/browse-mcp/pull/58","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/That1Drifter/browse-mcp/commit/5352a4a56f626254b445bfa07e4bb48c5aad15c1","tags":["x_refsource_MISC","fix","web"]},{"url":"https://github.com/That1Drifter/browse-mcp/blob/v0.8.2/CHANGELOG.md#082---2026-06-13","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/That1Drifter/browse-mcp/releases/tag/v0.8.2","tags":["x_refsource_MISC","web"]},{"url":"https://github.com/advisories/GHSA-m9mq-7m7q-xc6p"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/55xxx/CVE-2026-55557.json","tags":["advisory"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-55557","tags":["advisory"]},{"url":"https://github.com/That1Drifter/browse-mcp","tags":["package"]}],"sources":{"cve":[{"id":"CVE-2026-55557","title":"browse-mcp: Arbitrary file write via unconfined download and state paths","description":"browse-mcp is a Playwright-based headless-browser MCP server for MCP-capable agents. Prior to 0.8.2, browser_download writes a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, while browser_save_state and browser_load_state honor a caller-controlled path unchanged. A malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page, can choose an arbitrary save_dir or state path and a URL whose response body becomes attacker-controlled file contents, allowing writes to any path the process can reach, including ~/.bashrc, autostart entries, or cron files, and potentially leading to host code execution. The force_fetch fallback also uses a raw fetch() that bypasses the BROWSE_MCP_ALLOWED_ORIGINS origin fence. This issue is fixed in version 0.8.2.","status":"published","published":"2026-08-25T16:28:07.368Z","modified":"2026-08-25T19:00:25.437Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high","assessor":"cna"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:20:12.260247Z"}],"euvd":[{"id":"EUVD-2026-65581","description":"browse-mcp is a Playwright-based headless-browser MCP server for MCP-capable agents. Prior to 0.8.2, browser_download writes a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, while browser_save_state and browser_load_state honor a caller-controlled path unchanged. A malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page, can choose an arbitrary save_dir or state path and a URL whose response body becomes attacker-controlled file contents, allowing writes to any path the process can reach, including ~/.bashrc, autostart entries, or cron files, and potentially leading to host code execution. The force_fetch fallback also uses a raw fetch() that bypasses the BROWSE_MCP_ALLOWED_ORIGINS origin fence. This issue is fixed in version 0.8.2.","status":"published","published":"2026-08-25T16:28:07Z","modified":"2026-08-25T19:00:25Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"updated_at":"2026-11-02T18:01:32.174502Z"}],"ghsa":[{"id":"GHSA-m9mq-7m7q-xc6p","title":"browse-mcp has an arbitrary file write via unconfined download and state paths","description":"### Impact\n`browser_download` wrote a fetched file to `join(save_dir, filename)` with no validation of `save_dir`, and `browser_save_state` / `browser_load_state` honored an explicit `path` unchanged. The MCP caller controls these arguments (a malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page), so an attacker could supply an arbitrary `save_dir` (or state `path`) together with a URL whose response body became the file contents, writing attacker-controlled bytes to any path the process can reach (for example `~/.bashrc`, an autostart entry, or a cron file). That is an arbitrary file write that can lead to host code execution. The `force_fetch` fallback additionally used a raw `fetch()` that bypassed the `BROWSE_MCP_ALLOWED_ORIGINS` origin fence.\n\nEstimated severity: CVSS 3.1 around 7.8 (High) for the local / agent-mediated case.\n\n### Patches\nFixed in 0.8.2. `save_dir` is confined under the download root (`~/.browse-mcp/downloads`) and the explicit state `path` under `~/.browse-mcp/state`; absolute paths and `..` escapes are rejected, and download filenames are reduced to a bare basename. `force_fetch` now also honors the origin fence. Data roots remain relocatable via `BROWSE_MCP_HOME`. Upgrade to browse-mcp 0.8.2.\n\n### Workarounds\nRestrict the exposed tools with `BROWSE_MCP_TOOLS` to a set that excludes `browser_download`, `browser_save_state`, and `browser_load_state` (for example the hardened recipe in SECURITY.md). Note that the allowlist hides the tools from an agent but does not stop a malicious MCP client from calling them by name, so upgrading is the real fix.\n\n- Reported privately by novice-22.","status":"published","published":"2026-08-25T16:28:32Z","modified":"2026-08-25T16:28:33Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:41:05.994358Z"}],"nvd":[{"id":"CVE-2026-55557","description":"browse-mcp is a Playwright-based headless-browser MCP server for MCP-capable agents. Prior to 0.8.2, browser_download writes a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, while browser_save_state and browser_load_state honor a caller-controlled path unchanged. A malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page, can choose an arbitrary save_dir or state path and a URL whose response body becomes attacker-controlled file contents, allowing writes to any path the process can reach, including ~/.bashrc, autostart entries, or cron files, and potentially leading to host code execution. The force_fetch fallback also uses a raw fetch() that bypasses the BROWSE_MCP_ALLOWED_ORIGINS origin fence. This issue is fixed in version 0.8.2.","status":"published","published":"2026-08-25T17:17:32.357Z","modified":"2026-09-09T21:07:31.353Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","level":"high","assessor":"secondary"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T14:12:41.347728Z"}],"osv":[{"id":"CVE-2026-55557","title":"browse-mcp: Arbitrary file write via unconfined download and state paths","description":"browse-mcp is a Playwright-based headless-browser MCP server for MCP-capable agents. Prior to 0.8.2, browser_download writes a fetched response body to join(save_dir, filename) without validating the caller-controlled save_dir, while browser_save_state and browser_load_state honor a caller-controlled path unchanged. A malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page, can choose an arbitrary save_dir or state path and a URL whose response body becomes attacker-controlled file contents, allowing writes to any path the process can reach, including ~/.bashrc, autostart entries, or cron files, and potentially leading to host code execution. The force_fetch fallback also uses a raw fetch() that bypasses the BROWSE_MCP_ALLOWED_ORIGINS origin fence. This issue is fixed in version 0.8.2.","status":"published","published":"2026-08-25T16:28:07.368Z","modified":"2026-10-28T02:30:28.784896503Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:45:11.22012Z"},{"id":"GHSA-m9mq-7m7q-xc6p","title":"browse-mcp has an arbitrary file write via unconfined download and state paths","description":"### Impact\n`browser_download` wrote a fetched file to `join(save_dir, filename)` with no validation of `save_dir`, and `browser_save_state` / `browser_load_state` honored an explicit `path` unchanged. The MCP caller controls these arguments (a malicious MCP client, or an autonomous agent steered by indirect prompt injection on a visited page), so an attacker could supply an arbitrary `save_dir` (or state `path`) together with a URL whose response body became the file contents, writing attacker-controlled bytes to any path the process can reach (for example `~/.bashrc`, an autostart entry, or a cron file). That is an arbitrary file write that can lead to host code execution. The `force_fetch` fallback additionally used a raw `fetch()` that bypassed the `BROWSE_MCP_ALLOWED_ORIGINS` origin fence.\n\nEstimated severity: CVSS 3.1 around 7.8 (High) for the local / agent-mediated case.\n\n### Patches\nFixed in 0.8.2. `save_dir` is confined under the download root (`~/.browse-mcp/downloads`) and the explicit state `path` under `~/.browse-mcp/state`; absolute paths and `..` escapes are rejected, and download filenames are reduced to a bare basename. `force_fetch` now also honors the origin fence. Data roots remain relocatable via `BROWSE_MCP_HOME`. Upgrade to browse-mcp 0.8.2.\n\n### Workarounds\nRestrict the exposed tools with `BROWSE_MCP_TOOLS` to a set that excludes `browser_download`, `browser_save_state`, and `browser_load_state` (for example the hardened recipe in SECURITY.md). Note that the allowlist hides the tools from an agent but does not stop a malicious MCP client from calling them by name, so upgrading is the real fix.\n\n- Reported privately by novice-22.","status":"published","published":"2026-08-25T16:28:32Z","modified":"2026-08-26T00:05:58.82878506Z","cvss":[{"version":"4.0","score":8.6,"vector":"CVSS:4.0/AV:L/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-22"],"updated_at":"2026-11-02T15:46:51.811331Z"}]}}
