Security Advisory
Critical findings — no automatic redaction. Browser-use does not automatically scrub, redact, or filter passwords, credit card numbers, SSNs, or any other sensitive data from the browser state it sends to LLM APIs.
Browser-use does not automatically scrub, redact, or filter passwords, credit card numbers, SSNs, or any other sensitive data from the browser state it sends to LLM APIs. The library provides an opt-in sensitive_data parameter that can mask values you explicitly list, but it performs no structural detection of sensitive fields — it does not examine input type="password", apply Luhn-check filtering for card numbers, or pattern-match SSNs. The DOM representation includes the value attribute in its default attribute list with no type-based exclusions.
Several GitHub issues confirm real-world credential leakage in logs and LLM context. A peer-reviewed privacy study found the library disables Chromium password manager encryption on Linux, amplifying the risk surface.
DEFAULT_INCLUDE_ATTRIBUTES list — the set of HTML attributes serialized into the LLM context. There is no conditional logic that excludes value when the element's type="password". The get_meaningful_text_for_llm() method prioritizes value as its first attribute to read, before aria-label, placeholder, or any fallback — with no password-type awareness.
This means if a user fills a login form before the agent act, or if any form field has a pre-populated password value, that value travels to the LLM verbatim. Note: browsers typically do not expose password field .value via DOM inspection for security reasons, but the risk is real for any non-masked sensitive input.
sensitive_data parameter, which must be explicitly passed at agent construction. It works by replacing values you pre-specify with <secret>KEY</secret> placeholders — the real values are injected into form fields after the LLM call. Without this parameter, all browser state is sent to the LLM unfiltered.
If you don't know in advance what sensitive value the page will contain — a dynamically generated card number, a fetched account balance, an OTP — you cannot pre-register it. The library has no mechanism to detect and redact unknown sensitive patterns at runtime.
use_vision setting. When use_vision=True (the default in many configurations), the screenshot is sent directly to the LLM as an image — after which all text-layer filtering is meaningless. A password field that is visually unmasked on screen, a credit card form with pre-filled data, or any other visible sensitive content will be readable by the model from the image.
The documentation recommends disabling vision with use_vision=False to prevent screenshot-based exposure. This is not the default and must be manually set. It also recommends storage_state='./auth.json' for login cookies instead of passing passwords at all.
sensitive_data was configured and agent logs were redacted correctly, the controller logs in browser_use/controller/service.py exposed credentials in plaintext — visible in output as ⌨️ Input <actual_password> into index 3. This was reported in Issue #713 and patched in PR #724.
XXX-XX-XXXX), and no IBAN or account number detection in the browser-use codebase. If an agent visits a page displaying a credit card number, account balance, or tax identifier — in any DOM element that is serialized — that data passes to the LLM in full. The redact_sensitive_string function only replaces strings you have pre-registered; it does not pattern-match unknown PII.
No scrubbing of dynamically presented PII exists. If a banking portal shows account numbers inline in the DOM, and the agent is navigating it, those numbers enter the LLM context. The library provides no guardrail against this.
"little to no control over how that data is processed and shared."
— arXiv 2512.07725, Privacy Practices of Browser Agents (off-device data sharing)| Data Type | Auto-Detected | Opt-In Protection | Coverage Note |
|---|---|---|---|
| Password field (input type=password) | ✗ | ▲ Partial | Must pre-register; screenshots still expose value if vision on |
| Credit card numbers | ✗ | ✗ | No Luhn check or 16-digit pattern filtering |
| SSN / Tax IDs | ✗ | ✗ | No regex pattern matching for XXX-XX-XXXX or EIN |
| Bank account numbers | ✗ | ✗ | No IBAN, ABA, or account number detection |
| Pre-registered credentials (username/password) | ✗ | ✓ Opt-in | Works via sensitive_data dict; bypassed by screenshots |
| API keys / tokens (pre-registered) | ✗ | ✓ Opt-in | Same sensitive_data mechanism applies |
| Dynamically-rendered PII on page | ✗ | ✗ | No mechanism exists for unknown sensitive content |
Browser-use provides no automatic filtering of sensitive data. Protection exists only for values you explicitly pre-register via sensitive_data=, and even that is defeated by vision mode, historically leaked through controller logs, and has shipped with implementation bugs. No pattern-based scrubbing of credit cards, SSNs, or account numbers exists anywhere in the codebase.
use_vision=False for any task that touches authenticated pages or forms. Vision bypasses all text-layer filtering.sensitive_data= with allowed_domains= locked down. Omitting allowed_domains generates a warning; a prompt injection on any visited page can exfiltrate registered secrets.storage_state='./auth.json' to authenticate via session cookies so credentials never need to cross the LLM boundary.Sources