The vulnerability allowed a non-owner to gain owner privileges by spoofing the x-openclaw-sender-is-owner header in loopback requests to the MCP (Master Control Program). The root cause was a flaw in how the owner context was determined.
The analysis of the patch commit 3cb1a56bfc9579a0f2336f9cfa12a8a744332a19 reveals two key functions involved:
-
resolveMcpRequestContext: This function was directly responsible for the vulnerability. It read the x-openclaw-sender-is-owner header from the incoming request and used its value to set the senderIsOwner property in the request context. This is a classic case of trusting user-provided data for a security-critical decision.
-
validateMcpLoopbackRequest: This function was indirectly responsible. Its original implementation only validated a single bearer token, which authenticated the request as a valid loopback request but did not convey any information about the sender's privilege level (owner vs. non-owner). This design necessitated the use of the insecure header-based mechanism in resolveMcpRequestContext.
The fix addresses this by introducing two separate bearer tokens: one for owners (ownerToken) and one for non-owners (nonOwnerToken). The validateMcpLoopbackRequest function was updated to check for both tokens and securely determine the senderIsOwner status based on which token was provided. This status is then passed to resolveMcpRequestContext, removing the reliance on the spoofable header.
During exploitation, a profiler would show calls to validateMcpLoopbackRequest followed by resolveMcpRequestContext for every incoming MCP loopback request. An attacker would craft a request with the x-openclaw-sender-is-owner header set to true, and these functions would process it, leading to the privilege escalation.