Skip to content

[deep-review] C7: system.execApprovals.set validator accepts arbitrary file-path Allow rules #347

Description

@codemonkeychris

Summary

SystemCapability.HandleExecApprovalsSet validates rule patterns against a dangerous-fragment blocklist (Remove-Item, Format-, Shutdown, etc.) but does not reject Allow rules whose pattern is a specific arbitrary file path (e.g. "\\?\C:\evil.exe", "C:\Users\Public\m.exe"). The validator's broadest check covers all-wildcards and well-known shell prefixes ("powershell *", "cmd *"), but a specific binary path passes.

Where

  • Validator: src/OpenClaw.Shared/Capabilities/SystemCapability.cs:621-664 (ValidateExecApprovalRules)
  • Routing seam: src/OpenClaw.Shared/Capabilities/SystemCapability.cs:514 (HandleExecApprovalsSet)
  • Constraints surfaced to callers: :497-511

Why it matters

The local MCP HTTP server reaches this capability. A local untrusted process that obtained the MCP bearer token can rewrite the policy to whitelist an attacker-controlled binary path. The next system.run call to that binary is then allowed.

Two-step EoP:

  1. Compromise the MCP token (multiple paths).
  2. Rewrite policy to allow attacker binary.
  3. Invoke system.run against the binary.

The validator's existing defense-in-depth shape is good — it just has a gap on Allow-with-specific-path.

Proposed fix

Tighten ValidateExecApprovalRules so that:

  • If defaultAction != "prompt", Allow rules pointing at a specific executable path are rejected. Users must prompt-then-approve such a rule through the UI, not have it pushed by a remote .set.
  • Reject Allow rules whose pattern, after glob-to-regex conversion, would match any path containing \?\ (the long-path namespace prefix used by some bypass techniques).

Add tests:

  • Allow rule with pattern "C:\Users\Public\test.exe" → reject.
  • Allow rule with pattern "Get-*" (existing default) → still accepted.

Severity

High — local EoP requiring MCP token compromise as a prerequisite; defense-in-depth gap.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingsecurity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions