Back to skill

Security audit

OpenClaw Manager

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly coherent for OpenClaw operations, but its helper scripts can expose sensitive .env contents and allow misleading ledger entries.

Review this skill before installing in production workflows. It is not malicious, but users should avoid running the env validator where output is logged until malformed-line redaction is fixed, and should only pass trusted values to the ledger updater or store ledger records in a structured/sanitized format.

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

Warning
Location
scripts/validate_openclaw_env.py:218
Finding
Malformed Environment Lines Can Disclose Credentials Through Validation Output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/validate_openclaw_env.py`, lines 68–79, 218, and 233–235 **Vulnerability Type**: Sensitive information exposure through diagnostic output **Risk Level**: Medium ### Vulnerable Code ```python for idx, raw_line in enumerate(env_path.read_text().splitlines(), start=1): line = raw_line.strip() if not line or line.startswith("#"): continue if "=" not in line: malformed.append((idx, raw_line)) continue key, value = line.split("=", 1) key = key.strip() value = value.strip() if not KEY_RE.match(key): malformed.append((idx, raw_line)) continue ``` The complete malformed line is subsequently included in JSON output: ```python "malformed_lines": [{"line": line_no, "content": line} for line_no, line in malformed], ``` It is also printed in human-readable output: ```python if malformed: print("\nMalformed lines:") for line_no, line in malformed: print(f" - line {line_no}: {line}") ``` ### Technical Analysis The validator is explicitly designed to process `.env` files containing gateway tokens, model-provider API keys, and cloud-provider credentials. When a line does not contain `=` or has an invalid key name, the implementation retains the complete original line in `malformed`. The raw line is then emitted through both supported output modes: - JSON output includes the line in the `content` field. - Human-readable output prints the line directly to standard output. Malformed environment lines may still contain valid secret values. For example, an operator could accidentally use a space instead of an equals sign: ```text OPENAI_API_KEY sk-sensitive-value ``` Although this line is invalid as environment-file syntax, its sensitive value remains present and will be copied verbatim into validation output. That output may be collected by CI systems, deployment logs, agent transcripts, terminal recording systems, or su ...[truncated 1664 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Never include the original content of malformed environment lines in output. 2. Report only the line number and a generic parsing reason: ```python malformed.append((idx, "missing assignment separator")) ``` 3. Change JSON output to exclude a `content` field: ```python "malformed_lines": [ {"line": line_no, "reason": reason} for line_no, reason in malformed ] ``` 4. Change human-readable output accordingly: ```python for line_no, reason in malformed: print(f" - line {line_no}: {reason}") ``` 5. If displaying content is operationally required, apply robust redaction before storage or output. Redaction should cover both conventional `KEY=value` syntax and malformed strings containing token-like values. 6. Add regression tests using malformed lines that contain canary secrets and assert that no part of each canary appears in JSON or terminal output. 7. Document that validator output may be logged and must never contain environment values. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/update_openclaw_ops_ledger.py:43
Finding
Unescaped Ledger Fields Permit Persistent Markdown Content Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/update_openclaw_ops_ledger.py`, lines 43–55 and 78–96 **Vulnerability Type**: Persistent content injection into an operational record **Risk Level**: Medium ### Vulnerable Code Several arguments accept unrestricted text: ```python parser.add_argument("--ledger-file", required=True, help="Path to ledger markdown file") parser.add_argument("--event", required=True, choices=sorted(EVENT_CHOICES)) parser.add_argument("--operator", required=True) parser.add_argument("--mode", required=True) parser.add_argument("--provider", required=True) parser.add_argument("--os", required=True) parser.add_argument("--environment", required=True) parser.add_argument("--secrets-profile", required=True) parser.add_argument("--channels", default="") parser.add_argument("--integrations", default="") parser.add_argument("--security-status", required=True, choices=["pending", "passed", "failed"]) parser.add_argument("--blocking-issues", default="none") parser.add_argument("--rollback-tested", required=True, choices=["yes", "no"]) parser.add_argument("--next-owner", required=True) parser.add_argument("--next-action-date", required=True, help="YYYY-MM-DD") ``` Those values are directly interpolated into persistent Markdown: ```python entry = ( f"\n## {timestamp} | {args.event}\n" f"- operator: {args.operator}\n" f"- mode: {args.mode}\n" f"- provider: {args.provider}\n" f"- os: {args.os}\n" f"- environment: {args.environment}\n" f"- secrets_profile: {args.secrets_profile}\n" f"- channels: {channels}\n" f"- integrations: {integrations}\n" f"- security_status: {args.security_status}\n" f"- blocking_issues: {args.blocking_issues}\n" f"- rollback_tested: {args.rollback_tested}\n" f"- next_owner: {args.next_owner}\n" f"- next_action_date: {args.next_action_date}\n" ) with ledger_path.open("a", encoding="utf-8") as handle: handle.write(entry) ``` ### Technical Analys ...[truncated 2838 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject carriage returns, newlines, null bytes, and other control characters in every scalar field: ```python CONTROL_RE = re.compile(r"[\x00-\x1f\x7f]") def validate_scalar(name: str, value: str) -> str: if CONTROL_RE.search(value): raise ValueError(f"{name} contains prohibited control characters") return value ``` 2. Apply strict enumerations to fields with known values, including `mode`, `provider`, `os`, `environment`, and `secrets-profile`. 3. Validate `channels` and `integrations` against explicit allowlists rather than accepting arbitrary comma-separated strings. 4. Escape Markdown metacharacters if Markdown remains the canonical storage format. 5. Prefer writing canonical structured records, such as JSON Lines, with a separately generated Markdown view. Structured parsing prevents visual Markdown structure from becoming the security boundary. 6. Associate each entry with a unique run identifier and validate mandatory event ordering programmatically. 7. Where ledger integrity is security-critical, add authenticated integrity protection such as a signature or append-only storage with access controls. 8. Add tests that submit newline, heading, list-item, link, and HTML payloads in every free-form field and verify that they are rejected or safely encoded. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Rogue AgentSelf-Modification, Session Persistence
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description suggests a broad operational/deployment skill for OpenClaw, including secure deployment, runtime hardening, integration setup guidance, migration support, and incident response workflows. The supplied code chunk instead implements a narrow logging utility: it parses CLI flags, validates a date, ensures a ledger file exists, and appends a formatted markdown entry describing an event. This is materially different from the declared primary purpose. While ledgering could support operations workflows, this code does not itself provide deployment, hardening, troubleshooting, migration, or environment management functionality. Therefore the description does not accurately represent this code chunk’s actual behavior.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The declared description presents a comprehensive OpenClaw deployment and operations skill covering installation, hosting across multiple providers, secure defaults, onboarding, troubleshooting, migration, tuning, and incident response. The supplied code does not implement those capabilities. Instead, it is a single validation script focused specifically on checking .env configuration files against profile-specific key requirements and simple secret-quality heuristics. While env validation and a small amount of configuration hardening support the broader deployment domain, the actual code chunk’s primary purpose is much narrower and materially different from the declared skill scope. This is therefore a description-behavior mismatch.

Credential Access

High
Category
Privilege Escalation
Content
"- [ ] Append `scope_lock` entry to ops ledger.",
        "",
        "## 2. Preflight Validation",
        f"- [ ] Validate `.env` with `scripts/validate_openclaw_env.py --env-file .env --profile {profile}`.",
        "- [ ] Block progression on any validation failure.",
        "- [ ] Append `predeploy_validation` entry to ops ledger.",
        "",
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"- [ ] Append `scope_lock` entry to ops ledger.",
        "",
        "## 2. Preflight Validation",
        f"- [ ] Validate `.env` with `scripts/validate_openclaw_env.py --env-file .env --profile {profile}`.",
        "- [ ] Block progression on any validation failure.",
        "- [ ] Append `predeploy_validation` entry to ops ledger.",
        "",
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"- [ ] Append `scope_lock` entry to ops ledger.",
        "",
        "## 2. Preflight Validation",
        f"- [ ] Validate `.env` with `scripts/validate_openclaw_env.py --env-file .env --profile {profile}`.",
        "- [ ] Block progression on any validation failure.",
        "- [ ] Append `predeploy_validation` entry to ops ledger.",
        "",
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"- [ ] Append `scope_lock` entry to ops ledger.",
        "",
        "## 2. Preflight Validation",
        f"- [ ] Validate `.env` with `scripts/validate_openclaw_env.py --env-file .env --profile {profile}`.",
        "- [ ] Block progression on any validation failure.",
        "- [ ] Append `predeploy_validation` entry to ops ledger.",
        "",
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill instructs file-writing behavior via the operations ledger and references helper scripts that update local files, but it does not declare any explicit tool scope or allowed-tools boundaries. That omission weakens least-privilege controls and makes it easier for a consuming agent to perform unintended filesystem actions beyond what operators expect.

Session Persistence

Medium
Category
Rogue Agent
Content
| Infra ownership | Local machine/WSL resources | Cloud account + provider runtime |
| Exposure defaults | Private-first | Provider ingress with explicit auth controls |
| Required profile | `local` | `hosted-fly`, `hosted-render`, `hosted-railway`, `hosted-hetzner`, `hosted-gcp` |
| Rollback model | Restore local config/state snapshot | Redeploy prior revision + restore persisted state |

## Decision Rules
1. If user wants minimal setup and no cloud account, prefer `local`.
Confidence
55% 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.

Static analysis

No suspicious patterns detected.