Back to skill

Security audit

OpenClaw Route Audit

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for auditing OpenClaw cron routing, but its bundled audit script writes potentially sensitive results to predictable files in /tmp.

Review the helper script before installing. Use it only on a trusted single-user host or after changing it to use mktemp with restrictive permissions and cleanup; avoid running it as root unless required to read the OpenClaw files.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_route_audit.sh:23
Finding
Predictable Temporary Files Permit Local File Overwrite and Audit Data Disclosure## Vulnerability Details **File Location**: `scripts/run_route_audit.sh`, lines 23–25 **Vulnerability Type**: Predictable and insecure temporary-file handling **Risk Level**: Medium ### Vulnerable Code ```bash python3 "$DELIVERY_AUDIT" > /tmp/cron_delivery_audit.json "$ROUTE_CHECK_BIN" --all-crons --jobs "$JOBS_JSON" --json > /tmp/openclaw_route_check.json python3 -c 'import json; from pathlib import Path; print(json.dumps({"deliveryAudit": json.loads(Path("/tmp/cron_delivery_audit.json").read_text()), "routeAudit": json.loads(Path("/tmp/openclaw_route_check.json").read_text())}, indent=2))' ``` ### Technical Analysis The script stores audit results under fixed, predictable names in the globally writable `/tmp` directory. It neither creates these files atomically nor verifies that they are regular files owned by the invoking user. Shell output redirection follows symbolic links and truncates the destination before executing the associated command. A local attacker can therefore pre-create either output path as a symbolic link to another file. When a more privileged user runs the script, redirection may truncate or replace the linked file using that user's permissions. Alternatively, an attacker can pre-create an attacker-owned regular file at one of these paths. Because writing to an existing file does not necessarily change its ownership or restrictive properties, generated audit output may remain readable by the attacker. The risk is elevated by the script's use of resources under `/root/.openclaw`, which makes privileged execution plausible even though the documentation advises avoiding unnecessary elevated execution. ### Attack Path 1. A local attacker determines that the audit script uses `/tmp/cron_delivery_audit.json` and `/tmp/openclaw_route_check.json`. 2. Before the audit runs, the attacker either: - creates one of those paths as a symbolic link to a file writable by the eventual invoking user; or - creates an attacker-owned file at that ...[truncated 1220 chars]
Remediation
## Remediation Suggestions Create a unique private temporary directory, restrict newly created files to the current user, and ensure cleanup on every exit path: ```bash umask 077 TMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-route-audit.XXXXXX")" trap 'rm -rf -- "$TMP_DIR"' EXIT DELIVERY_OUTPUT="$TMP_DIR/cron_delivery_audit.json" ROUTE_OUTPUT="$TMP_DIR/openclaw_route_check.json" python3 "$DELIVERY_AUDIT" > "$DELIVERY_OUTPUT" "$ROUTE_CHECK_BIN" --all-crons --jobs "$JOBS_JSON" --json > "$ROUTE_OUTPUT" python3 - "$DELIVERY_OUTPUT" "$ROUTE_OUTPUT" <<'PY' import json import sys from pathlib import Path delivery_path, route_path = map(Path, sys.argv[1:]) print(json.dumps({ "deliveryAudit": json.loads(delivery_path.read_text()), "routeAudit": json.loads(route_path.read_text()), }, indent=2)) PY ``` Additional hardening measures: - Continue advising users not to run the script with elevated privileges unless strictly necessary. - Avoid fixed filenames in any shared writable directory. - Keep `umask 077` so audit results are not readable by other users. - Use an `EXIT` trap to remove potentially sensitive output even if an audit command fails. - If persistent output is required, write it to a user-controlled directory with restrictive permissions rather than `/tmp`.
Vulnerability Patterns
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Self-Modification

High
Category
Rogue Agent
Content
- keep the skill read-only by default
- avoid embedding secrets, tokens, webhook URLs, cookies, chat ids beyond public examples already present in the user’s config
- avoid curl-to-shell installers in the skill
- avoid auto-download or self-update behavior
- prefer pinned local paths and deterministic commands
- include the upstream repository link in SKILL.md
- list required local paths and prerequisites explicitly
Confidence
90% confidence
Finding
Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Missing User Warnings

Low
Confidence
92% confidence
Finding
The script writes potentially sensitive audit output to fixed paths under /tmp, a world-accessible temporary directory. This can expose internal job and route audit data to other local users and also creates a symlink/race-condition risk where an attacker pre-creates those paths to read or redirect the output.

Static analysis

No suspicious patterns detected.