high · 8.8Jul 2, 2026

CVE-2026-53821: openclaw Trusted-Proxy WebSocket Scope Elevation

Shubham Kandhare
Security Engagement Manager, SecureLayer7

A restricted or unpaired OpenClaw user on a trusted-proxy deployment could declare admin-level permissions on a WebSocket connection before the server ever verified those permissions, then use that…

Packageopenclaw
Ecosystemnpm
Affected< 2026.5.18
Fixed in2026.5.18

The problem

OpenClaw's Control UI WebSocket handshake in trusted-proxy mode accepted whatever operator scopes the client declared in the x-openclaw-scopes upgrade header. The gateway cached those scopes on the live connection before any server-side pairing or authorization baseline was checked.

Any user who could open a Control UI WebSocket under a restricted trusted-proxy identity could self-declare operator.admin. That cached authority persisted for the lifetime of the connection and could be used to call admin-gated Gateway RPCs such as config.get, exec.approvals.set, and similar.

Proof of concept

A working proof-of-concept for this issue in openclaw, with the exact payload below.

http
GET /ws HTTP/1.1
Host: gateway.internal:18789
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
X-Forwarded-User: restricted-user@example.com
X-Forwarded-For: 10.0.0.1
x-openclaw-scopes: operator.admin

# After the WS connection is established, call an admin-gated RPC:
# {"jsonrpc":"2.0","method":"config.get","params":{},"id":1}

Before 2026.5.18, the gateway applied the client-declared x-openclaw-scopes header directly to the WebSocket session cache without first confirming the session was bound to a server-approved paired device or an authorized trusted-proxy baseline. This is a Missing Authorization flaw (CWE-862) combined with Incorrect Authorization (CWE-863): the scope was sourced from attacker-controlled input, not from a server-side grant.

The patch cleared the scope list to [] for any device-less Control UI WebSocket session, meaning the server now ignores client-declared scopes unless a valid pairing or authorization baseline is already confirmed. The x-openclaw-scopes header was reclassified as a cap on negotiated scopes, not a grant of them.

The fix

Upgrade to openclaw@2026.5.18 or later. As an interim measure, restrict trusted-proxy Control UI access to users who already hold the scopes they need, and restart the gateway after any trusted-proxy authorization policy change. Do not rely on gateway.controlUi.dangerouslyDisableDeviceAuth=true in production, as it bypasses the scope-clearing fix.

Reported by Andres Murillo (@handmilkingsoftware).

References: [1][2]

Related research