-
-
Notifications
You must be signed in to change notification settings - Fork 53k
Description
Summary
The device.token.rotate endpoint allows an authenticated device to escalate its own scopes beyond what was originally approved during pairing, enabling privilege escalation from a limited device role to full admin access.
Executive Risk Snapshot
- CVSS v3.1: 8.1 (High)
- CVSS v4.0: 8.6 (High)
- Primary risk: The
device.token.rotateendpoint allows an authenticated device to escalate its own scopes beyond what was originally approved during pairing, enabling privilege escalation from a limited device role to full admin access.
Technical Analysis
The vulnerability is reachable through a production code path where untrusted input can influence security-sensitive behavior without sufficient invariant enforcement. Current evidence indicates impact consistent with the summary: The device.token.rotate endpoint allows an authenticated device to escalate its own scopes beyond what was originally approved during pairing, enabling privilege escalation from a limited device role to full admin access.
Affected Code
File: openclaw/src/infra/device-pairing.ts:289-312
export async function rotateDeviceToken(params: {
deviceId: string;
role: string;
scopes?: string[];
baseDir?: string;
}): Promise<DeviceAuthToken | null> {
return await withLock(async () => {
const state = await loadState(params.baseDir);
const context = resolveDeviceTokenUpdateContext({
state,
deviceId: params.deviceId,
role: params.role,
});
if (!context) {
return null;
}
const { device, role, tokens, existing } = context;
const requestedScopes = normalizeDeviceAuthScopes(
params.scopes ?? existing?.scopes ?? device.scopes, // <-- VULNERABILITY: Uses requested scopes
);
// ... no validation that requestedScopes are subset of allowed scopes
const now = Date.now();
const next = buildDeviceAuthToken({
role,
scopes: requestedScopes, // <-- Assigns requested scopes without validation
existing,
now,
rotatedAtMs: now,
});
// ...
});
}Steps to Reproduce
- Pair a device with limited scopes (e.g.,
operator.read) - Call
device.token.rotatewithscopes: ["operator.admin"] - Observe that the new token has
operator.adminscope - Use the new token to access admin-only endpoints
Recommended Fix
Validate that requested scopes are a subset of the device's originally approved scopes:
Detailed Risk Analysis
CVSS Assessment
| Metric | v3.1 | v4.0 |
|---|---|---|
| Score | 8.1 / 10.0 | 8.6 / 10.0 |
| Severity | High | High |
| Vector | CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N | CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N |
| Calculator | CVSS v3.1 Calculator | CVSS v4.0 Calculator |
Attack Surface
Reachable via network access to the affected interface. The device.token.rotate endpoint allows an authenticated device to escalate its own scopes beyond what was originally approved during pairing, enabling privilege escalation from a limited device role to full admin access. Exploitation requires low privileges.
Exploit Conditions
Exploitation complexity is low, and user interaction is none. Prerequisites include the vulnerable workflow being enabled and attacker access meeting the required privilege level.
Impact Assessment
Confidentiality impact is high, integrity impact is high, and availability impact is none. Scope is unchanged.
References
- CWE: CWE-269 - Improper Privilege Management
Exploitability Proof
A paired device can escalate privileges by:
- Initial pairing with limited scopes:
{
"deviceId": "attacker-device",
"role": "observer",
"scopes": ["operator.read"]
}- Call rotate with escalated scopes:
{
"method": "device.token.rotate",
"params": {
"deviceId": "attacker-device",
"role": "observer",
"scopes": ["operator.admin", "operator.read", "operator.write"]
}
}- The
rotateDeviceTokenfunction accepts the new scopes without checking againstdevice.scopes
Mitigation Checks Performed
- Checked
scopesAllowfunction: Exists but is only used inverifyDeviceToken, not inrotateDeviceToken - Checked for scope validation in pairing approval: Scopes are stored but not enforced on rotation
- Checked gateway method authorization: Uses scopes from token, not from device record
Reproduction Evidence
The code path shows:
rotateDeviceTokenacceptsscopesparameter from caller- Normalizes them via
normalizeDeviceAuthScopes - Assigns them directly to the new token without validation
- The
scopesAllowhelper exists but is not called in this flow
Why This Is Exploitable (Not Hardening)
This is a real vulnerability because:
- The
scopesAllowfunction exists and is used for verification, proving the developers understand scope validation - Scope validation is intentionally implemented in
verifyDeviceTokenbut omitted fromrotateDeviceToken - This allows any paired device to escalate to admin privileges
- The impact is critical: admin scope grants full system control