T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- scripts/root_session_guard.py:278
- Finding
- Privileged Approval State Can Be Forged Through the Public State Helper<![CDATA[ ## Vulnerability Details **File Location**: `scripts/root_session_guard.py:278-349` **Vulnerability Type**: Unauthenticated privileged-approval state mutation **Risk Level**: High ### Vulnerable Code ```python def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="OpenClaw root/elevated session guard") parser.add_argument( "--state-file", default=str(STATE_PATH), help="Path to session state JSON file", ) parser.add_argument( "--timeout-minutes", type=int, default=DEFAULT_TIMEOUT_MINUTES, help="Idle timeout for elevated mode", ) sub = parser.add_subparsers(dest="command", required=True) sub.add_parser("preflight", help="Check timeout and approval requirement") authz = sub.add_parser( "authorize", help="Authorize a specific argv against the current elevated allowlist", ) authz.add_argument( "--argv-json", required=True, help='Command argv as JSON array, e.g. ["launchctl","print","..."]', ) authz.add_argument("--session-id", help="Task session id to scope approvals") approve = sub.add_parser( "approve", help="Approve a specific argv for elevated execution (adds to allowlist)", ) approve.add_argument("--reason", required=True, help="Approval reason") approve.add_argument( "--argv-json", required=True, help='Command argv as JSON array, e.g. ["launchctl","print","..."]', ) approve.add_argument("--session-id", help="Task session id to scope approvals") sub.add_parser("elevated-used", help="Mark elevated mode as used now") sub.add_parser("normal-used", help="Mark normal mode activity now") sub.add_parser("drop", help="Drop to normal mode") sub.add_parser("status", help="Print current state and timeout info") return parser.parse_args() def main() -> int: args = parse_args() state_file = Path( ...[truncated 3098 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Remove the directly callable `approve` state mutation operation from the public helper interface. - Keep approval and state mutation in one trusted process so another local process cannot invoke the mutation independently. - Alternatively, require a short-lived, single-use, cryptographically authenticated approval capability generated only after interactive consent. - Bind the capability to the canonical argv, session ID, user identity, expiration time, and nonce. - Verify state-file ownership and permissions before every read and write, and reject symlinks or unexpected file types. - Use atomic state updates with restrictive permissions such as mode `0600`. - Make task-session scoping mandatory rather than optional. - Add regression tests proving that direct invocation of the helper cannot create an accepted approval. ]]>
