# Risk map — browser-use/browser-use

> Canonical page: https://codevetter.com/unpack/browser-use/risk-map

# Risk map — browser-use/browser-use

Scanned commit d8110c5ff87ccba887aaa726cdb780f2f84bef8d (2026-09-15). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

The highest-risk surfaces are arbitrary page JavaScript, the remote sandbox that cloudpickles and ships user code, secret substitution, file upload and external file reads, and domain policy that is off unless configured. Several controls exist and are tested (domain filter, IP blocking, upload whitelist, sensitive-data redaction), but the JavaScript evaluate path only fixes quotes, the flat sensitive_data format is global, and CrashWatchdog is disabled. Docs in AGENTS.md disagree with Agent.__init__ defaults, which is a trap for agents editing call sites.
- evaluate sends the model-supplied string to CDP Runtime.evaluate with awaitPromise and returnByValue after _validate_and_fix_javascript, which only rewrites escaped quotes, regex escapes, and a few selector quote styles. There is no script allowlist or CSP wrapper. — [browser_use/tools/service.py#L1833-L2006](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L1833-L2006)
- @sandbox base64-encodes cloudpickle.dumps of the closure and sends the reconstructed source plus pickled params to sandbox.api.browser-use.com with the API key in X-API-Key. That is remote code execution of whatever the decorated function closes over. — [browser_use/sandbox/sandbox.py#L305-L370](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/sandbox/sandbox.py#L305-L370)
- Legacy sensitive_data entries that are plain strings (not nested under a domain pattern) are merged into applicable_secrets for every URL. Domain-scoped entries are filtered with match_url_with_domain_pattern. Missing placeholders are logged, not raised. — [browser_use/tools/registry/service.py#L449-L514](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/registry/service.py#L449-L514)
- read_file treats a string that is exactly in available_file_paths as an external file and opens that path with anyio.open_file, python-docx, or pypdf. The check is equality, not a resolved-path containment check. upload_file has the same membership test. — [browser_use/tools/service.py#L864-L909](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L864-L909) [browser_use/tools/service.py#L1795-L1802](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/tools/service.py#L1795-L1802) [browser_use/filesystem/file_system.py#L671-L704](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L671-L704)
- FileSystem.__init__ deletes and recreates base_dir/browseruse_agent_data with shutil.rmtree when that subdirectory already exists. Passing a file_system_path that already contains a browseruse_agent_data directory wipes it. — [browser_use/filesystem/file_system.py#L506-L516](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/filesystem/file_system.py#L506-L516)
- SecurityWatchdog allows every URL when both allowed_domains and prohibited_domains are unset. disable_security on BrowserProfile appends CHROME_DISABLE_SECURITY_ARGS to the Chrome launch flags. block_ip_addresses defaults to False. — [browser_use/browser/watchdogs/security_watchdog.py#L209-L220](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/watchdogs/security_watchdog.py#L209-L220) [browser_use/browser/profile.py#L625-L639](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/profile.py#L625-L639)
- ProductTelemetry is on by default (ANONYMIZED_TELEMETRY defaults true) and sends events to https://eu.i.posthog.com with a project API key hardcoded in telemetry/service.py. The device id is persisted at ~/.config/browseruse/device_id or derived from MAC and hostname. Opt out with ANONYMIZED_TELEMETRY=false. — [browser_use/telemetry/service.py#L21-L94](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/telemetry/service.py#L21-L94) [.env.example#L18-L20](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/.env.example#L18-L20) [browser_use/config.py#L57-L60](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/config.py#L57-L60)
- Crash recovery is not wired: the CrashWatchdog import and event subscriptions inside attach_all_watchdogs are comments. Browser disconnects are handled instead by Agent._handle_step_error waiting on browser_session._reconnect_event. — [browser_use/browser/session.py#L1698-L1716](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/session.py#L1698-L1716) [browser_use/agent/service.py#L1268-L1284](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L1268-L1284)
- AGENTS.md documents Agent defaults that do not match the constructor: code uses max_steps=500 on run(), max_actions_per_step=5, max_failures=5, step_timeout=180, and use_vision=True. The checked-in agent guide still says max_steps 100, max_actions_per_step 3, max_failures 3, step_timeout 120, and use_vision 'auto'. — [browser_use/agent/service.py#L169-L199](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L169-L199) [browser_use/agent/service.py#L2503-L2508](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/agent/service.py#L2503-L2508) [AGENTS.md](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/AGENTS.md)
- browser_use/controller/__init__.py only re-exports Controller, which is an alias of Tools. browser_use/beta/service.py duplicates a large slice of Agent (it imports the same history, judge, and message-manager types) and is excluded from pyright as a dynamic beta wrapper. — [browser_use/controller/__init__.py#L1-L3](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/controller/__init__.py#L1-L3) [browser_use/beta/service.py#L1-L80](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/beta/service.py#L1-L80) [pyproject.toml#L165-L167](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/pyproject.toml#L165-L167)
- MCP mode inserts the package parent onto sys.path, disables logging below CRITICAL, and can run a full Agent (retry_with_browser_use_agent) inside the MCP client process. A compromised or overly broad MCP client therefore gets the same browser and filesystem powers as the library. — [browser_use/mcp/server.py#L29-L99](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/mcp/server.py#L29-L99) [browser_use/mcp/server.py#L391-L400](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/mcp/server.py#L391-L400)
- Cloud browser and LLM calls send the API key in headers (X-Browser-Use-API-Key and the chat client's own auth). create_browser logs the live URL at info level. stop_browser PATCHes /api/v2/browsers/{id} with action stop. — [browser_use/browser/cloud/cloud.py#L38-L93](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/cloud/cloud.py#L38-L93) [browser_use/browser/cloud/cloud.py#L106-L152](https://github.com/browser-use/browser-use/blob/d8110c5ff87ccba887aaa726cdb780f2f84bef8d/browser_use/browser/cloud/cloud.py#L106-L152)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
