Skip to content

[Bug]: Device Token Scope Escalation via Rotate Endpoint #20702

@coygeek

Description

@coygeek

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.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.

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

  1. Pair a device with limited scopes (e.g., operator.read)
  2. Call device.token.rotate with scopes: ["operator.admin"]
  3. Observe that the new token has operator.admin scope
  4. 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:

  1. Initial pairing with limited scopes:
{
  "deviceId": "attacker-device",
  "role": "observer",
  "scopes": ["operator.read"]
}
  1. Call rotate with escalated scopes:
{
  "method": "device.token.rotate",
  "params": {
    "deviceId": "attacker-device",
    "role": "observer",
    "scopes": ["operator.admin", "operator.read", "operator.write"]
  }
}
  1. The rotateDeviceToken function accepts the new scopes without checking against device.scopes

Mitigation Checks Performed

  • Checked scopesAllow function: Exists but is only used in verifyDeviceToken, not in rotateDeviceToken
  • 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:

  1. rotateDeviceToken accepts scopes parameter from caller
  2. Normalizes them via normalizeDeviceAuthScopes
  3. Assigns them directly to the new token without validation
  4. The scopesAllow helper exists but is not called in this flow

Why This Is Exploitable (Not Hardening)

This is a real vulnerability because:

  1. The scopesAllow function exists and is used for verification, proving the developers understand scope validation
  2. Scope validation is intentionally implemented in verifyDeviceToken but omitted from rotateDeviceToken
  3. This allows any paired device to escalate to admin privileges
  4. The impact is critical: admin scope grants full system control

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions