Back to skill

Security audit

OpenClaw Safe Upgrade Rehearsal Kit

Security checks for vulnerabilities and agentic risk

Overview

This skill is mainly a disclosed read-only OpenClaw upgrade rehearsal, with some adjacent benchmark tooling that users should treat as optional and trusted-only.

Install only if you want an OpenClaw upgrade rehearsal that reads package metadata, downloads npm package evidence, writes local evidence artifacts, and may hash paths you explicitly declare in observation specs. Do not pass secrets into advisory reviews, and only use the benchmark --advisory-adapter with a local executable you already trust.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (22)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The description says this skill is for rehearsing an OpenClaw update and producing compatibility-gap and migration/rollback/post-start verification planning based on package evidence and Kova reports. The supplied code does not do upgrade rehearsal or migration planning. Instead, it is a benchmark runner: it verifies a frozen corpus, executes benchmark arms over fixture prompt payloads, optionally calls a configured advisory adapter, scores the outputs against frozen scoring keys, and emits evaluation artifacts. The module repeatedly states it is 'evaluation-only' and that 'canonical_status_effect' is none. While it is a sibling to rehearsal tooling and imports a rehearsal-related error class, its primary purpose is materially different from the declared description.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The code is a reporting/view-generation script, not a rehearsal or planning tool. It loads existing JSON artifacts such as verdict.json and impact-shadow.json, validates limited schema fields, and emits Markdown summarizing status, evidence file presence, required gates, and repository/run links. The declared description claims a substantive pre-upgrade rehearsal with exact package evidence, installation coverage, Kova reports, and preparation for migration/rollback/post-start verification. None of that planning or analytical workflow is implemented here beyond displaying already-produced artifact contents. In fact, the output explicitly warns that preflight does not prove migration, rollback, or post-activation behavior, which directly undercuts the declared purpose. Therefore the description materially overstates and mischaracterizes the code’s actual behavior.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The file content is materially misaligned with the declared skill purpose: instead of an OpenClaw safe-update rehearsal workflow, it documents a benchmark runner and reporting framework. In a security-sensitive agent skill, this mismatch is dangerous because operators may enable or trust capabilities they did not intend to expose, including subprocess-based adapter execution and artifact generation paths outside the expected update-rehearsal scope.

Self-Modification

High
Category
Rogue Agent
Content
2. Migration/restore rehearsal consumes the same `candidate_root` and emits
   disposable evidence. It cannot activate the candidate.
3. Activation planning records an external approval requirement and keeps live
   E2E `not_run`. The safe-update skill stops here.
4. After a separately controlled activation, an operational capability may
   create a forward-reconcile handoff. That capability owns its approval,
   rollback, and containment semantics.
Confidence
85% 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.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The file implements a benchmark runner with optional external adapter execution rather than a narrowly scoped safe-update rehearsal utility as described in the skill metadata. This mismatch increases security risk because reviewers or operators may grant the skill permissions or trust assumptions appropriate for rehearsal/reporting, while the code actually introduces a broader execution and evaluation surface.

YARA rule 'agent_skill_prompt_injection_hidden_instructions': Prompt injection or hidden instructions embedded in AI agent skill text [agent_skills]

High
Category
YARA Match
Content
,
    "LANG",
    "LC_ALL",
    "NODE_EXTRA_CA_CERTS",
    "NO_PROXY",
    "PATH",
    "PATHEXT",
    "SSL_CERT_DIR",
    "SSL_CERT_FILE",
    "SYSTEMROOT",
    "TEMP",
    "TMP",
    "TMPDIR",
    "USERPROFILE",
    "all_proxy",
    "http_proxy",
    "https_proxy",
    "no_proxy",
)

# Deterministic arms run as fixed deterministic identities; they never
# inherit the operator-supplied (advisory) model family.
DETERMINISTIC_WORKER_ID = "openclaw-benchmark-deterministic"
DETERMINISTIC_MODEL_FAMILY = "deterministic"

# Authority-bearing keys the advisory worker has no right to emit. Their
# presence (in the runner envelope or the raw result) is a blocked-verdict
# signal: the worker tried to assert a canonical block it cannot own. This
# is distinct from a false-unaffected claim and never weakens the #15
# result schema, which the worker output must still satisfy.
BLOCKED_VERDICT_KEYS = frozenset(
    {
        "verdict",
        "block",
        "blocked",
        "decision",
        "d
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Context-Inappropriate Capability

High
Confidence
97% confidence
Finding
The advisory adapter mechanism allows execution of an arbitrary external command unrelated to the declared update-rehearsal purpose. Even with shell=False and some validation, the adapter receives structured input and selected environment variables, making it a powerful extension point that can run attacker-controlled or untrusted local code and potentially exfiltrate data or manipulate the host.

Credential Access

High
Category
Privilege Escalation
Content
except OSError as exc:
        raise RehearsalError("cannot create isolated npm cache") from exc
    execution_dir = working_dir or cache_dir
    project_config = execution_dir / ".npmrc"
    try:
        if project_config.exists() and project_config.read_bytes():
            raise RehearsalError(
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
except OSError as exc:
        raise RehearsalError("cannot create isolated npm cache") from exc
    execution_dir = working_dir or cache_dir
    project_config = execution_dir / ".npmrc"
    try:
        if project_config.exists() and project_config.read_bytes():
            raise RehearsalError(
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
except OSError as exc:
        raise RehearsalError("cannot create isolated npm cache") from exc
    execution_dir = working_dir or cache_dir
    project_config = execution_dir / ".npmrc"
    try:
        if project_config.exists() and project_config.read_bytes():
            raise RehearsalError(
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
except OSError as exc:
        raise RehearsalError("cannot create isolated npm cache") from exc
    execution_dir = working_dir or cache_dir
    project_config = execution_dir / ".npmrc"
    try:
        if project_config.exists() and project_config.read_bytes():
            raise RehearsalError(
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill instructs execution of Python and npm-based commands, reads and writes local files, and performs network package metadata/archive retrieval, yet it declares no explicit tool scope or permission boundaries. In an agent platform, that gap can cause the skill to run with broader-than-expected shell, filesystem, environment, and network access, increasing the blast radius if the skill is invoked in an unsafe context.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The skill enables implicit invocation without any visible activation constraints, so the agent may trigger this capability automatically based on vague user intent rather than an explicit user request. Even though the described action is a read-only upgrade rehearsal, it can still cause unintended environment inspection, package inventory collection, and disclosure of operational details in contexts where the user did not knowingly authorize this skill.

Skill Enumeration

Medium
Category
Agent Snooping
Content
{
      "id": "mcporter-skill-contract",
      "kind": "member_contains",
      "member": "package/skills/mcporter/SKILL.md",
      "needle": "mcporter",
      "package": "openclaw"
    }
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
{
      "id": "mcporter-skill-contract",
      "kind": "member_contains",
      "member": "package/skills/mcporter/SKILL.md",
      "needle": "mcporter",
      "package": "openclaw"
    }
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Intent-Code Divergence

Medium
Confidence
87% confidence
Finding
The documentation asserts that the runner is not a network client and opens no sockets, yet it also permits execution of an external advisory adapter whose behavior is outside the runner's control. That inconsistency can create a false sense of safety: an operator may assume no network-capable behavior exists, while the invoked adapter could perform network access, exfiltration, or other unreviewed actions under local credentials or environment.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The document defines an execution/reporting subsystem that is not justified by the manifest's stated update-rehearsal purpose, expanding the apparent operational scope of the skill. Even if presented as evaluation-only, unrelated execution logic increases attack surface and can confuse downstream agents or reviewers into invoking tooling with broader behavior than expected.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
raise BenchmarkError("adapter command not found")
    argv[0] = executable
    try:
        completed = subprocess.run(
            argv,
            shell=False,
            input=json.dumps(advisory_input, ensure_ascii=True),
Confidence
94% confidence
Finding
The code executes an operator-supplied external command via subprocess.run. Although shell=False, shlex splitting, PATH resolution, timeout, and bounded output reduce classic injection risk, this still permits arbitrary program execution in the skill runtime if a malicious or mistaken adapter command is provided. In an agent skill context, invoking external binaries materially expands the trust boundary and can lead to code execution, data exfiltration, or unsafe side effects by the adapter.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def detect_node_version() -> str:
    try:
        completed = subprocess.run(
            [resolve_runtime_command("node"), "--version"],
            check=True,
            capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
}
    )
    try:
        completed = subprocess.run(
            [resolve_runtime_command("npm"), *arguments],
            cwd=execution_dir,
            check=True,
Confidence
91% confidence
Finding
This code executes `npm` with argument lists that are partially derived from user-provided package names and versions, causing network fetches and package resolution against the public npm registry. Although `shell=True` is not used and scripts are disabled, invoking external package tooling on untrusted inputs still expands attack surface through dependency confusion, npm/parser bugs, malicious registry content handling, or execution of an attacker-controlled `npm` binary via PATH.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def command_version(command: str) -> str:
    try:
        completed = subprocess.run(
            [resolve_runtime_command(command), "--version"],
            check=True,
            capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
if command_override is None and cache_dir is not None:
        command.extend(["--cache-dir", str(cache_dir)])
    try:
        completed = subprocess.run(
            command,
            check=False,
            capture_output=True,
Confidence
86% confidence
Finding
This code launches a subprocess based on a command list that may be replaced by the `unit_runner`/`command_override` pathway, and in the default path re-invokes the current Python interpreter on the same script while embedding JSON metadata as a command-line argument. While shell injection is avoided, this still creates exposure to unsafe interpreter/script resolution, argument-size abuse, and execution of unintended binaries if the runtime environment is compromised or if extension points are misused.

Static analysis

No suspicious patterns detected.