CVSS Assessment
| Metric |
Value |
| Score |
9.9 / 10.0 |
| Severity |
Critical |
| Vector |
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H |
CVSS v3.1 Calculator
Summary
/elevated authorization accepts ctx.To as an identity token, so recipient identifiers can satisfy sender allowlists. In WhatsApp inbound DM flows, To is set to the bot's own number for each message, allowing non-owner senders to pass tools.elevated.allowFrom.whatsapp checks when that allowlist contains the owner/self number.
This elevates the session to full when /elevated full is accepted, and embedded-agent exec calls then bypass approval prompts (ask=off).
Affected Code
File: source_code/src/auto-reply/reply/reply-elevated.ts:103
addToken(params.ctx.SenderName);
addToken(params.ctx.SenderUsername);
addToken(params.ctx.SenderTag);
addToken(params.ctx.SenderE164);
addToken(params.ctx.From);
addToken(stripSenderPrefix(params.ctx.From));
addToken(params.ctx.To);
addToken(stripSenderPrefix(params.ctx.To));
File: source_code/src/web/inbound/monitor.ts:303
const inboundMessage: WebInboundMessage = {
id,
from,
conversationId: from,
to: selfE164 ?? "me",
// ...
};
File: source_code/src/web/auto-reply/monitor/process-message.ts:279
const ctxPayload = finalizeInboundContext({
// ...
From: params.msg.from,
To: params.msg.to,
// ...
});
File: source_code/src/auto-reply/reply/get-reply-run.ts:395
bashElevated: {
enabled: elevatedEnabled,
allowed: elevatedAllowed,
defaultLevel: resolvedElevatedLevel ?? "off",
},
File: source_code/src/agents/pi-embedded-runner/run/attempt.ts:210
createOpenClawCodingTools({
exec: {
...params.execOverrides,
elevated: params.bashElevated,
},
// ...
});
File: source_code/src/agents/bash-tools.exec.ts:946
const bypassApprovals = elevatedRequested && elevatedMode === "full";
if (bypassApprovals) {
ask = "off";
}
Attack Surface
How is this reached?
Authentication required?
Entry point: Inbound channel message with /elevated on|ask|full directive (for example WhatsApp DM).
Exploit Conditions
Complexity:
User interaction:
Prerequisites:
tools.elevated.enabled=true
tools.elevated.allowFrom.whatsapp includes the owner/self E.164
- Attacker is already allowed to send command-capable inbound messages (for example paired/allowlisted sender)
Impact Assessment
Scope:
What can an attacker do?
| Impact Type |
Level |
Description |
| Confidentiality |
High |
Read arbitrary host data by running privileged exec flows after /elevated full. |
| Integrity |
High |
Execute host commands that modify files/config/state outside intended per-sender controls. |
| Availability |
High |
Disrupt service by running destructive or terminating commands without approval prompts. |
Steps to Reproduce
- Configure WhatsApp inbound with at least two command-capable senders (owner + another sender), and set
tools.elevated.allowFrom.whatsapp to the owner/self E.164.
- From the non-owner sender, send
/elevated full.
- Observe the directive is accepted (
Elevated mode set to full (auto-approve).).
- Send a normal message that causes the embedded agent to invoke
exec (for example, ask it to run id or list files on host).
- Observe host exec runs without approval prompts because exec defaults now resolve to elevated
full (ask=off).
Notes
!id / !ls go through the /bash command path, which currently creates a separate exec tool with defaultLevel: "on" (ask-level), so that specific command form is not the approval-bypass path for this bug.
Recommended Fix
Use only sender-authenticated identities for elevated authorization. Remove ctx.To (and its stripped variant) from the token set. Prefer stable sender IDs (SenderId, provider-native immutable IDs, E.164 where applicable) over mutable display names. Treat recipient/conversation fields as routing metadata, never authorization principals.
References
- CWE: CWE-285 - Improper Authorization
CVSS Assessment
Summary
/elevatedauthorization acceptsctx.Toas an identity token, so recipient identifiers can satisfy sender allowlists. In WhatsApp inbound DM flows,Tois set to the bot's own number for each message, allowing non-owner senders to passtools.elevated.allowFrom.whatsappchecks when that allowlist contains the owner/self number.This elevates the session to
fullwhen/elevated fullis accepted, and embedded-agent exec calls then bypass approval prompts (ask=off).Affected Code
File:
source_code/src/auto-reply/reply/reply-elevated.ts:103File:
source_code/src/web/inbound/monitor.ts:303File:
source_code/src/web/auto-reply/monitor/process-message.ts:279File:
source_code/src/auto-reply/reply/get-reply-run.ts:395File:
source_code/src/agents/pi-embedded-runner/run/attempt.ts:210File:
source_code/src/agents/bash-tools.exec.ts:946Attack Surface
How is this reached?
Authentication required?
Entry point: Inbound channel message with
/elevated on|ask|fulldirective (for example WhatsApp DM).Exploit Conditions
Complexity:
User interaction:
Prerequisites:
tools.elevated.enabled=truetools.elevated.allowFrom.whatsappincludes the owner/self E.164Impact Assessment
Scope:
What can an attacker do?
/elevated full.Steps to Reproduce
tools.elevated.allowFrom.whatsappto the owner/self E.164./elevated full.Elevated mode set to full (auto-approve).).exec(for example, ask it to runidor list files on host).full(ask=off).Notes
!id/!lsgo through the/bashcommand path, which currently creates a separate exec tool withdefaultLevel: "on"(ask-level), so that specific command form is not the approval-bypass path for this bug.Recommended Fix
Use only sender-authenticated identities for elevated authorization. Remove
ctx.To(and its stripped variant) from the token set. Prefer stable sender IDs (SenderId, provider-native immutable IDs, E.164 where applicable) over mutable display names. Treat recipient/conversation fields as routing metadata, never authorization principals.References