Security Brief — Browser Automation / LLM Payload Analysis · Browser Use (Python) & OpenClaw · Technical Research Issued 2026-06-23  ·  Verification: 6 claims / 2 refuted  ·  Sources: 20+

LLM API Payload Analysis

What leaves your network when the agent looks at a page

Both tools send a structured snapshot of the browser's live state to a cloud LLM on every step. Neither performs automatic redaction of passwords, account numbers, or SSNs. This briefing documents exactly what is in the payload, confirmed against source code.

Auto-redaction of sensitive data
None — design gap in both tools
Form values incl. passwords sent to LLM
Yes — by default
Claims verified / refuted
6 verified / 2 refuted
sensitive_data mechanism
Opt-in allowlist; confirmed failure mode
EXHIBIT

Simulated outbound payload — what your LLM API receives each agent step

POST /v1/messages
"role": "user"
"content": [
  { "type": "text",
    "text": "<task>Log in to the banking portal and check my balance</task>"
    URL: https://bank.example.com/login | Tab 1 of 1
    Scroll: 0% (Start of page)
    Interactive elements: 4

[1]<input type=text placeholder=Username name=username [email protected] />
[2]<input type=password name=password value=Tr0ub4dor&3 />
[3]<button type=submit>Sign In</button>
[4]<a href=/forgot-password>Forgot password?</a>

"type": "image_url", "url": "data:image/png;base64,iVBORw0KGgo...[screenshot truncated, ~180KB]"

— Simulated outbound payload, base text + element list + screenshot (set A)

── with sensitive_data configured ──
[1]<input type=text value=<account_username> />  ← text layer replaced
[2]<input type=password value=<account_password> />  ← text layer replaced
"type": "image_url", "url": "data:image/png;base64,iVBORw0KGgo...[screenshot: credentials VISIBLE in image] ←

— With sensitive_data: text layer is replaced, but the screenshot still shows credentials
Warning

── account summary page (no sensitive_data configured for this content) ──
Checking ****4821 balance: $12,450.33 ← sent verbatim; no auto-detection
Routing: 021000089  Account: 000123456789 ← sent verbatim

SECTION 01

Payload contents — what the LLM API receives each step

Not raw HTML — a serialized, indexed AX snapshot Confirmed
Detail Browser Use does not send the page's raw HTML to the LLM. It fires three parallel Chrome DevTools Protocol (CDP) requests per step — DOM.getDocument, the accessibility (AX) tree across all frames, and DOMSnapshot.captureSnapshot — then merges the results into a numerically-indexed element list. Each interactive element receives an integer reference: [42]<input type=email placeholder="[email protected]" />. That indexed list is what goes in the text portion of the LLM message.
OpenClaw OpenClaw uses a similar "Semantic Markdown" serialization derived from Playwright's aria-ref system, converting the page into role-annotated text with numeric reference IDs.
Source browser_use/dom/serializer/service.pyDOMTreeSerializer.serialize_tree() & llm_representation(). Serialized output is capped at 40,000 characters.
Form field values — incl. passwords — in element list Key finding
Detail The serializer includes the value attribute in its DEFAULT_INCLUDE_ATTRIBUTES list. The get_meaningful_text_for_llm() method reads value first, before any fallback, with no branch that checks for type="password". A password field whose value is set — either by autofill, the agent's own prior action, or the page itself — will appear as value=PlaintextPassword in the serialized tree sent to the API.
Confirm This is confirmed by GitHub Issue #713 (February 2025), which documented passwords appearing verbatim in controller logs from the same extraction pipeline. The log fix was patched in PR #724, but the underlying field inclusion behavior in the LLM payload is unchanged.
Note The same data sent to logs was also sent to the LLM API. Patching the log output did not patch the payload.PAYLOAD UNCHANGED
Screenshots bypass text-layer substitution Key finding
Detail When use_vision=True (the default in many configurations), a base64-encoded PNG screenshot is appended to the LLM message after the text element list. The screenshot is a full render of the visible viewport — whatever the user's screen would show. Any content visible on the page is visible in the screenshot, regardless of what the text-layer redaction mechanism does.
Docs The Browser Use docs acknowledge this explicitly: they recommend use_vision=False when working on pages containing sensitive data. That setting is not the default, and there is no per-domain vision control.
Source browser_use/agent/prompts.pyAgentMessagePrompt.get_user_message(). Screenshots are also resized via PIL before encoding; this does not affect their content.
Data TypeSent to LLM API?Format / Notes
Raw HTML sourceNoNever included in standard prompt path
Full unfiltered DOMNoFiltered to interactive/visible elements only
Accessibility tree (indexed)Yes — alwaysPrimary signal; merged DOM+AX+snapshot, capped at 40k chars
Form field values (incl. passwords)Yes — by defaultvalue attr included; no type="password" exclusion
Screenshots (base64 PNG)ConditionalSent when use_vision=True; bypasses text-layer redaction
Extracted page textOn extract action onlyMarkdown-converted via markdownify; not included on every step
Agent action historyYes — alwaysCondensed; compacted to a summary block for long tasks
Tab URLs and titlesYes — alwaysAll open tabs reported in page metadata block
Shadow DOM elementsYes — when accessibleCDP pierce: true traverses shadow roots; depth-limited to 100 iframes
SECTION 02

Sensitive data handling — what exists, what it covers, where it fails

No automatic detection of passwords / PANs / SSNs Critical
Detail Neither Browser Use nor OpenClaw performs heuristic or pattern-based detection of sensitive data in the browser state before sending it to the LLM API. There is no Luhn check for credit card numbers, no SSN regex (XXX-XX-XXXX), no IBAN detection, and no special handling of type="password" input elements. If a page renders account numbers, routing numbers, or partial card numbers as visible text — as most banking and financial portals do — those values go to the API verbatim, in the indexed accessibility snapshot.
Note This is a design gap, not a configuration option. There is nothing to enable.DESIGN GAP
Browser Use: opt-in sensitive_data parameter Partial mitigation
Detail Browser Use provides a sensitive_data parameter on the Agent constructor. You pass a dictionary mapping domain names to key-value pairs of credentials. The library replaces those exact values with placeholder tokens (e.g., <account_password>) in the text-layer portion of the LLM message. The LLM reasons with the placeholder; the actual value is substituted only when the agent takes an action that requires it (e.g., typing into a field).
Covers What this covers: exact string values you explicitly pre-register, scoped to specified domains.
Misses What this does not cover: any sensitive value not in the dictionary (account numbers seen on the page, other users' data, dynamic tokens), and anything visible in a screenshot when use_vision=True.ALLOWLIST ONLY
Source The mechanism is documented in browser_use/utils.pyredact_sensitive_string(). It is a simple string replacement loop. The library emits a warning if sensitive_data is set without also setting allowed_domains.
GitHub Issue #1062 — silent failure with some OpenAI models Active bug
Detail GitHub Issue #1062 (open as of this writing) documents a failure mode where the sensitive_data substitution mechanism inserts the literal placeholder key string into the action instead of the real value — meaning the agent types <account_password> into a login field rather than the actual password. The failure is silent; no error is raised. The issue is confirmed with specific OpenAI model configurations and has no workaround in the library itself.
Status Open. The sensitive_data path is not a first-class guarantee — it is best-effort with a confirmed failure mode in production.OPEN
SECTION 03

Known incidents and confirmed vulnerabilities

IncidentDetailStatus
browser-use Issue #713 — Feb 2025 Passwords in plaintext controller logs. Filed against browser_use/controller/service.py#L137. Passwords entered by the agent appeared unmasked in logs even when agent-level log masking was active. Root cause: the same extraction pipeline that builds the LLM payload also fed log output with no filtering. Patched in PR #724 (log output only). Patched (logs only)
browser-use Issue #695 — Feb 2025 Sensitive data keys entered into forms instead of values. Related to #1062. The placeholder substitution mechanism populated form fields with the dictionary key name rather than the registered credential value. Partially addressed; recurred in #1062. Partially addressed
browser-use Issue #1062 — 2025 (open) sensitive_data silently fails with OpenAI models. Agent types literal placeholder string into input fields. No exception raised. Confirmed in production. No fix merged at time of research. Open
browser-use/web-ui — SSRF via LLM API Base URL field LLM API key leakage via unvalidated Base URL. The web-ui companion project contained an SSRF vulnerability where an attacker-controlled base URL field could redirect API requests (including auth headers containing the LLM API key) to an arbitrary host. Filed as Issue #168 in the web-ui repo. Patched
arXiv 2512.07725 — Academic Study, 2025 8 browser agents, 30 vulnerabilities documented. Peer-reviewed study covering Browser Use among others. Key finding: Browser Use disables Chromium password encryption on Linux by default when launching a managed browser profile, leaving saved credentials unencrypted on disk and amplifying prompt injection risk. Prompt injection via malicious page content can direct the agent to exfiltrate secrets already in its context window. No fix (design behavior)
OpenClaw — Cross-session context leakage (2026) Secrets from one user session visible to other users. Giskard security analysis found that secrets loaded into OpenClaw's global context for one session were accessible to other sessions sharing the same gateway instance. Separately, environment variables and API keys were exposed via group chat interfaces. Additionally, a critical RCE via WebSocket hijacking from malicious websites was identified. Partially mitigated
SECTION 04

Browser Use vs. OpenClaw — what each tool is and how they relate

Note

These are separate products. OpenClaw is not a fork of Browser Use. OpenClaw is an open-source self-hosted AI personal assistant (messaging-app gateway + task executor) that can optionally use Browser Use as a browser automation backend. The Browser Use docs list OpenClaw as an integration. The two can be used independently.

Browser Use Python library
TypePython library for browser automation via LLM
Primary signalIndexed DOM+AX+snapshot tree (text); optional screenshot
Raw HTML sentNo
Auto-redactionNone. Opt-in explicit allowlist only.
Vision defaultuse_vision='auto' — model-dependent
Key sourcesagent/prompts.py, dom/serializer/service.py, utils.py
LicenseApache 2.0
OpenClaw Self-hosted gateway
TypeSelf-hosted AI assistant gateway (messaging + task runner)
Primary signalSemantic Markdown from Playwright aria-ref AX tree; optional screenshot
Raw HTML sentNo (filtered DOM extract in some modes)
Auto-redactionNone for browser snapshots. Log redaction config available.
Vision defaultModel-dependent; screenshot sent when vision LLM configured
Security concernCross-session leakage, RCE via WebSocket (2026 Giskard)
LicenseMIT
SECTION 05

What you can actually do — mitigations ranked by effectiveness

Set use_vision=False on all sensitive pages. Screenshots sent to the LLM cannot be filtered by text-layer redaction. Disabling vision eliminates the image channel entirely. This is the only way to prevent credential autofill or on-screen account numbers from appearing in the image payload. Trade-off: the agent loses layout context for complex UIs.

Configure sensitive_data with allowed_domains for all credentials the agent must use. Pre-register every credential the agent will type. This covers the values you know. It does not cover dynamic data the page renders (account numbers, balances). Always pair with allowed_domains — without it, the library emits a warning and the scoping guarantee does not apply.

Do not use a shared browser profile with saved passwords. Browser Use launches Chromium and disables password encryption on Linux. Any saved credentials in the profile are unencrypted on disk and may be surfaced to the agent via autofill. Use an isolated, fresh profile with no saved credentials for agent tasks.

Avoid automating pages that render full account numbers, SSNs, or card numbers. There is no library-level detection for these patterns. If the task requires navigating a page that displays them, they will appear in the accessibility snapshot verbatim. The only mitigation is to design the workflow so the agent never reaches those pages, or terminates before the data is rendered.

For OpenClaw: run a single-user instance; do not expose the gateway to untrusted group chats. The cross-session context leakage documented by Giskard occurs in multi-user gateway configurations. A single-user local instance removes the inter-session exposure vector. Disable the WebSocket interface or restrict it to localhost to mitigate the RCE vector.

Validate that sensitive_data substitution is actually working on your model. Issue #1062 confirms the mechanism silently fails with some OpenAI model configurations. Before deploying to production, run a test step where the agent must type a registered credential and verify that the placeholder (not the literal placeholder key, not the real value) appears in the LLM message trace. Enable full API call logging during this test.

Section 06 — Sources

[1] github.com/browser-use/browser-use — Source repository. Key files: browser_use/agent/prompts.py, browser_use/dom/serializer/service.py, browser_use/agent/message_manager/service.py, browser_use/utils.py [2] browser-use Issue #713 — "Sensitive data does not work on controller log" (Feb 2025, patched PR #724) [3] browser-use Issue #1062 — sensitive_data silently fails with OpenAI models (open) [4] arXiv 2512.07725 — Browser agent security study: 8 agents, 30 vulnerabilities including Chromium encryption disabled on Linux [5] github.com/openclaw/openclaw — OpenClaw source and documentation [6] docs.browser-use.com/cloud/tutorials/integrations/openclaw — Browser Use / OpenClaw integration documentation [7] Giskard Security Analysis (2026) — OpenClaw cross-session leakage, group chat env var exposure, WebSocket RCE [8] arXiv 2508.04412 — "Beyond Pixels: Exploring DOM Downsampling for LLM-Based Web Agents" — confirms indexed AX-tree approach [9] browser-use/web-ui Issue #168 — SSRF via unvalidated LLM Base URL field, leading to API key exfiltration (patched)