Back to skill

Security audit

OpenClaw Upgrader

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent OpenClaw upgrader, but it grants and scripts high-impact local upgrade authority with under-scoped delegation and concrete runner vulnerabilities.

Review before installing. This skill is meant to change a live OpenClaw installation, restart or repair services, write files under the OpenClaw user area, and potentially contact Codex or Claude Code. It should be tightened before general use: fix the result-path Python injection, make lock ownership cleanup safe, require explicit user confirmation before external AI preflights and service/package changes, and restrict delegate command selection to trusted configured paths.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run-upgrade-delegation.sh:217
Finding

Arbitrary Python Code Execution Through an Unsafely Embedded Result Path

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run-upgrade-delegation.sh:34
Finding

Unconditional Cleanup Can Remove a Lock Owned by Another Upgrade Run

Content
View full analysis
/dev/null 2>&1 || true rmdir "$LOCK_DIR" >/dev/null 2>&1 || true } ``` It is installed as an unconditional exit handler before context collection establishes whether this process acquired the lock: ```bash trap release_lock EXIT # --- Phase 1: Context collection (also claims the lock) --- if [[ -z "$CONTEXT_JSON" ]]; then TS="$(date +%Y%m%d-%H%M%S)" CONTEXT_JSON="$HOME/.openclaw/upgrade-context-$TS.json" fi "$COLLECTOR" "$TARGET_VERSION" "$CONTEXT_JSON" >/dev/null ``` The trap is removed only after the collector successfully returns and the generated context is parsed as a rejected re-entry: ```bash if [[ "$DELEGATION_STATUS" == "rejected_reentry" ]]; then trap - EXIT write_terminal_result "rejected_reentry" \ '"delegation_status": "rejected_reentry", "delegation_block_reason": "active_run_exists"' exit 0 fi ``` ### Technical Analysis The lock directory is host-global by default: ```bash LOCK_DIR="${OPENCLAW_UPGRADER_LOCK_DIR:-$HOME/.openclaw/openclaw-upgrader.lock}" ``` The context collector attempts to acquire that lock with an atomic `mkdir`. When the directory already exists, the collector records a rejected-reentry result rather than taking ownership. However, the outer runner installs `trap release_lock EXIT` before calling the collector. If context collection fails before the runner reaches the explicit `rejected_reentry` branch, `set -e` causes the outer script to exit and invoke `release_lock`. The cleanup function does not compare the current run identifier, PID, or any ownership token against `run.json`; it simply deletes the shared metada ...[truncated 2237 chars]
Remediation
View remediation
/dev/null || true )" [[ -n "$EXPECTED_RUN_ID" && "$recorded_run_id" == "$EXPECTED_RUN_ID" ]] || return 0 rm -f -- "$LOCK_INFO_FILE" rmdir -- "$LOCK_DIR" } ``` 6. Install `trap release_lock EXIT` only after setting and verifying `LOCK_OWNED=true`. 7. Prefer an operating-system lock primitive such as `flock` where supported, while retaining a secure cross-platform alternative. 8. Include an unpredictable ownership token in the lock metadata rather than relying solely on a PID or timestamp. 9. Use atomic writes for `run.json` and validate its ownership and permissions. 10. Add tests covering collector failure, malformed context JSON, unwritable context paths, signals, rejected re-entry, and concurrent invocations. Each test should verify that a non-owner can never remove the active owner's lock. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (12)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 34)May include surrounding context.

md
Use `scripts/collect-upgrade-context.sh` to gather a machine-readable context snapshot before delegation. That script must reject re-entry before agent prefligh

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 79)May include surrounding context.

md
Use `scripts/collect-upgrade-context.sh` to gather a machine-readable context snapshot before delegation. That script must reject re-entry before agent prefligh

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill describes file-writing behavior such as config backups and result-file creation, and it delegates upgrade actions that can modify the local system, but it does not declare an explicit tool scope like allowed-tools or permissions. That omission weakens least-privilege controls and can cause the runtime or delegated agent to operate with broader capabilities than the user expects, increasing the blast radius if the skill or downstream prompt is misused.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This section instructs the workflow to back up config and write structured result artifacts, which are persistent local file modifications, but the skill does not explicitly warn the user that files will be created or changed. That creates a transparency and consent problem: users may invoke what sounds like an upgrade helper without realizing it will write backups, lock metadata, or result files onto disk.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · SKILL.md (reported line 81)May include surrounding context.

md
The run lock must cover the entire active upgrader lifecycle, not just context collection. `scripts/collect-upgrade-context.sh` may claim the host-level run lock and emit lock metadata, but the caller/outer runner must retain that lock until the delegated upgrade run reaches a terminal state and then release it deliberately. `scripts/run-upgrade-delegation.sh` is the default outer-runner scaffold for this purpose and must remain responsible for terminal lock release.

If delegation cannot begin, OpenClaw itself must write a structured pre-delegation failure result. Do not leave blocked delegation as an implicit or unstructured failure.
If another upgrader run is already active on this host, reject re-entry or explicitly queue it; do not allow concurrent execution.

Useful facts to pass:

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The delegated workflow explicitly includes package upgrades, service-definition refresh, restart, recovery, and verification, all of which can alter system packages and running services, yet the skill does not clearly warn the user that invoking it may change system state and interrupt service availability. In context, this is more dangerous than ordinary file writes because it can restart or reconfigure the active OpenClaw service and potentially affect local clients or system stability.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script’s so-called context collection step executes live AI agent CLIs (codex exec and claude -p) as a preflight check, which can trigger network access, transmit environment-derived context, and perform side effects before the main upgrade workflow begins. That exceeds passive inspection and creates an unexpected trust boundary crossing during a preparatory phase, especially since users may not realize that merely gathering upgrade context will contact external services.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The preflight commands invoke external AI CLIs without any user-visible warning or confirmation, so a user running an upgrade helper may unknowingly trigger outbound requests and prompt execution. In this script’s context, collected values such as endpoint, auth mode, service identity, and filesystem paths increase the sensitivity of what could be exposed or inferred by those tools.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill is described as a Codex-supervised upgrader, yet the script silently probes Claude as an alternate execution path and may delegate to it if Codex is unavailable. This expands the external attack and data-exposure surface beyond the documented tool, undermines user expectations, and could route upgrade-related context to an unrelated provider or CLI with different security properties.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The header promises the lock is held until a terminal state, but in the OPENCLAW_UPGRADER_DELEGATE_CMD path the wrapper exits and releases the lock even if the delegate wrote a nonterminal or malformed result. That can allow a second upgrade run to start while the first upgrade may still be incomplete or inconsistent, creating race conditions around service restart, state migration, or recovery.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Lines L106-L110 document the EXIT trap as guaranteeing the lock is always released regardless of how the script terminates. However, lines L229-L231 explicitly remove that trap so the lock survives process exit when no delegate command is wired, which directly contradicts the earlier assurance rather than merely omitting detail.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script executes a command entirely controlled by the OPENCLAW_UPGRADER_DELEGATE_CMD environment variable. In the context of an upgrade skill that may run with elevated privileges and manipulates service state, any attacker able to influence that environment can achieve arbitrary code execution under the script's privileges.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.