Back to skill

Security audit

Fix CLI Device Scope

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed repair tool, but it directly grants broad admin-level OpenClaw device permissions and rewrites local authentication state.

Install only if you intentionally want a local recovery tool that can rewrite OpenClaw device trust and authentication files. Prefer an official pairing or admin approval flow where available, verify the target device and requested scopes first, keep backups, avoid --force, and treat operator.talk.secrets and approval/pairing scopes as highly sensitive.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/fix.py:27
Finding

Direct Authorization Bypass and Broad Device Privilege Escalation

Content
View full analysis

Vulnerability Details

File Location: scripts/fix.py:27-34, 44-50, 101-162, 177-191; SKILL.md:66-71, 117-118
Vulnerability Type: Direct modification of trusted authentication state, unsafe privilege assignment, and approval bypass
Risk Level: High

Vulnerable Code

scripts/fix.py:27-34 defines a broad fallback permission set that includes administrative, approval, pairing, write, and secret-access capabilities:

python
FALLBACK_SCOPES = [
    "operator.admin",
    "operator.read",
    "operator.write",
    "operator.approvals",
    "operator.pairing",
    "operator.talk.secrets",
]

scripts/fix.py:44-50 trusts the scopes contained in the first repair request without validating them against a restrictive allowlist:

python
def find_device_id_from_pending():
    """从 pending repair 请求获取设备 ID"""
    if not os.path.exists(PENDING):
        return None, None
    with open(PENDING) as f:
        pending = json.load(f)
    for req in pending.values():
        if req.get("isRepair"):
            return req.get("deviceId"), req.get("scopes", FALLBACK_SCOPES)
    return None, None

scripts/fix.py:101-162 generates a new privileged token, directly rewrites trusted pairing and authentication files, and deletes matching pending requests:

python
def fix(device_id, full_scopes, dry_run=False, force=False):
    """执行修复"""
    new_token = f"cli_admin_{secrets.token_urlsafe(20)}"
    ts = int(datetime.now().timestamp() * 1000)

    # Read current state
    with open(PAIRED) as f:
        paired = json.load(f)
    with open(AUTH) as f:
        auth = json.load(f)

    if device_id not in paired:
        red(f"设备 {device_id} 不在 paired.json 中!")
        red(f"可用设备: {list(paired.keys())}")
        sys.exit(1)

    old_scopes = paired[device_id].get("scopes", [])

    # Show changes first (检查点!)
    show_changes(device_id, old_scopes, full_scopes, n
...[truncated 5579 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove direct trust-database modification. Do not grant scopes by editing paired.json or device-auth.json. Use OpenClaw's official authenticated pairing and approval APIs.
  2. Require independent administrative approval. Scope elevation must be authorized by an already trusted administrator rather than by the device requesting elevation.
  3. Remove or strictly restrict --force. Noninteractive privilege elevation should not be available to ordinary callers. If automation is essential, require a separately protected administrative credential and explicit policy authorization.
  4. Apply a minimal scope allowlist. Never trust scope arrays read from pending.json. Parse and validate every requested scope, reject unknown or excessive values, and grant only the minimum permissions required for the specific repair.
  5. Avoid the broad fallback scope set. Failure to locate a valid, authenticated request should terminate safely rather than automatically granting administrative, pairing, approval, write, and secret-access scopes.
  6. Verify device identity and request provenance. Bind each repair request cryptographically to the requesting device and verify that the request is current, authentic, and intended for the exact device being modified.
  7. Preserve audit evidence. Record the request, approver identity, old and new scopes, timestamp, and outcome in an append-only audit log. Do not silently delete pending records as part of elevation.
  8. Use transactional and atomic updates. If local state must be updated, write validated data to securely created temporary files, preserve restrictive file permissions and ownership, flush data, atomically replace the originals, and roll back all changes if any step fails.
  9. Do not replace complete token maps unnecessarily. Avoid deleting unrelated token metadata or roles when updating one operator credential.
  10. Add negative security tests. Tes ...[truncated 196 chars]
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script defines broad fallback scopes including operator.admin and operator.talk.secrets, and later applies them when no pending repair request is found. In this skill’s context, the tool is specifically meant to bypass insufficient device permissions, so granting expansive privileges without deriving them from an authenticated repair request creates an authorization-escalation path rather than a narrow repair action.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs running shell commands and executing Python scripts that modify local device pairing/authentication state, but it does not declare any explicit tool scope or allowed-tools boundary. That creates an authorization gap: an orchestrator or reviewer cannot easily tell that the skill needs shell and file-write capability before invocation, increasing the chance of over-privileged or unintended execution against sensitive config files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language instructions, triggers, and operational guidance are entirely in Chinese, with no indication that the skill is intentionally region-specific or that users may opt into another language. Under the stated policy, forcing a specific language without user choice is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger phrases are broad and partly underspecified, including generic operational failure terms like 'spawn失败', 'cron失败', and '死循环'. In this skill, accidental invocation is more dangerous than usual because the prescribed remediation changes authentication tokens/scopes and edits pairing-related files, so an overbroad trigger could cause the wrong recovery workflow to be suggested or applied to unrelated incidents.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code file contains user-facing natural-language text exclusively in Chinese, starting with the module docstring and continuing throughout status and summary output. The policy requires flagging language or locale constraints when the skill forces a specific language without user opt-in, and there is no indication that users can select another language or that the locale restriction is justified.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/diagnose.py (reported line 25)May include surrounding context.

python
def check_gateway():
    info("检查 Gateway 状态...")
    r = subprocess.run(["openclaw", "gateway", "status"], capture_output=True, text=True)
    if "running" in r.stdout:
        green("Gateway 正在运行")
    else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/verify.py (reported line 79)May include surrounding context.

python
def check_gateway():
    info("检查 Gateway 状态...")
    r = subprocess.run(["openclaw", "gateway", "status"], capture_output=True, text=True)
    if "running" in r.stdout:
        green("Gateway 正在运行")
    else:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/diagnose.py (reported line 34)May include surrounding context.

python
def check_devices():
    info("检查设备列表...")
    r = subprocess.run(["openclaw", "devices", "list"], capture_output=True, text=True)
    lines = r.stdout.strip().split("\n")
    # Find CLI devices
    cli_devices = []

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The top-level documentation frames the behavior as writing full scopes into paired.json. The implementation performs additional side effects: it updates the local auth token store and deletes matching pending repair entries, so the docstring understates and therefore misrepresents what the script actually changes.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This file contains natural-language instructions, usage text, and status messaging exclusively in Chinese. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script does more than repair metadata: it generates a fresh operator token and writes it into both paired.json and device-auth.json. Because the new token is bound to the elevated scopes being assigned, this directly provisions usable credentials for an admin-capable device, turning a repair utility into a credential-issuance mechanism.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script claims to verify that the scope fix succeeded, but it never performs a real spawn authorization test and instead asks the operator to do it manually. In this skill context, that can create a false sense of security around device/admin scope repair, causing operators to restart and trust a still-broken or inconsistently scoped setup that affects privileged agent actions like subagent, spawn, and cron.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.