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:
- Compromise the MCP token (multiple paths).
- Rewrite policy to allow attacker binary.
- 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.
Summary
SystemCapability.HandleExecApprovalsSetvalidates rule patterns against a dangerous-fragment blocklist (Remove-Item,Format-,Shutdown, etc.) but does not rejectAllowrules 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
src/OpenClaw.Shared/Capabilities/SystemCapability.cs:621-664(ValidateExecApprovalRules)src/OpenClaw.Shared/Capabilities/SystemCapability.cs:514(HandleExecApprovalsSet):497-511Why 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.runcall to that binary is then allowed.Two-step EoP:
system.runagainst 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
ValidateExecApprovalRulesso that:defaultAction != "prompt",Allowrules 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.Allowrules whose pattern, after glob-to-regex conversion, would match any path containing\?\(the long-path namespace prefix used by some bypass techniques).Add tests:
Allowrule with pattern"C:\Users\Public\test.exe"→ reject.Allowrule with pattern"Get-*"(existing default) → still accepted.Severity
High — local EoP requiring MCP token compromise as a prerequisite; defense-in-depth gap.