Back to skill

Security audit

clawguard

Security checks for vulnerabilities and agentic risk

Overview

clawguard is a local security-review skill whose behavior matches its stated purpose, with a privacy caveat because saved reports can include source excerpts.

Before installing, understand that clawguard saves local review reports and those reports may preserve snippets from files it scans. Do not point it at broad private directories or files containing real credentials unless you are comfortable with those snippets being copied into the local workspace report store.

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/lib/engine.py:169
Finding
Potential Secrets Are Persisted in Plaintext Without Redaction or Restrictive Permissions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/lib/engine.py:169-178`; `scripts/lib/storage.py:11-12, 32-38` **Vulnerability Type**: Plaintext storage of potentially sensitive information **Risk Level**: Medium ### Vulnerable Code `scripts/lib/engine.py:169-178`: ```python findings.append({ "rule_id": rule["rule_id"], "title": rule["title"], "severity": rule["severity"], "matched_file": rel_path, "matched_line": line_no, "evidence": stripped[:300], "why_it_matters": rule["why_it_matters"], "recommendation": rule["recommendation"], "fix_command": rule["fix_command"] }) ``` `scripts/lib/storage.py:11-12, 32-38`: ```python MEMORY_DIR = os.path.join(get_workspace_root(), "memory", "clawguard") REPORTS_PATH = os.path.join(MEMORY_DIR, "reports.json") ``` ```python def save_report(report): data = load_reports() data["reports"][report["report_id"]] = report data["metadata"]["last_updated"] = datetime.utcnow().isoformat() with open(REPORTS_PATH, "w", encoding="utf-8") as f: json.dump(data, f, indent=2, ensure_ascii=False) ``` ### Technical Analysis The scanner's rules intentionally detect credential-related material, including passwords, tokens, API keys, private keys, authorization headers, and explicit secret-exposure instructions. When a source line matches one of these rules, `scan_skill()` copies up to 300 characters from the line into the report's `evidence` field without masking credential values. `save_report()` then writes the complete report to `reports.json` in the OpenClaw workspace. The file is plaintext and is opened without explicitly enforcing a restrictive permission mode such as `0600`. Consequently, its effective permissions depend on the process umask or the permissions of a previously existing file. The implementation also has no retention limit, report deletion mechanism, or redaction step. The behavior is local and no network transmission was found. The static p ...[truncated 1677 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Redact secrets before constructing findings** - Replace credential values with fixed placeholders such as `[REDACTED]`. - Preserve only the rule identifier, file path, line number, and a sanitized excerpt. - Apply redaction for common assignment, header, URL, JSON, PEM, and environment-variable formats. 2. **Minimize retained evidence** - Do not persist complete matching lines for credential-related rules. - Consider recording only the matched pattern category and a short, sanitized context window. - Add a mode that displays sensitive evidence transiently without saving it. 3. **Enforce restrictive storage permissions** - Create `MEMORY_DIR` with mode `0700`. - Create `reports.json` with mode `0600`, for example using `os.open()` with explicit flags and permissions. - Verify permissions on existing files and refuse unsafe symbolic links before writing. 4. **Use safer writes** - Write to a securely created temporary file in the same protected directory. - Flush and atomically replace the destination. - Ensure neither the temporary file nor destination can be redirected through a symbolic-link attack. 5. **Add lifecycle controls** - Provide commands to delete individual reports and purge all stored reports. - Support configurable expiration and maximum report counts. - Document that reports may contain sensitive source excerpts. 6. **Add regression tests** - Scan representative API keys, bearer tokens, passwords, private-key material, and authorization headers. - Assert that none of the raw values appear in saved reports. - Assert that report files and directories receive the intended restrictive permissions. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The declared purpose describes a substantive security review and risk auditing capability. The supplied code chunk only initializes storage and outputs the reports path. While storage setup could be a supporting utility for a larger auditing system, this chunk by itself does not implement the declared auditing behavior and instead has a materially different immediate purpose: filesystem/storage initialization.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
Administrator privileges, sensitive path access, and system-level modification tendencies.

“自动修复”“绕过限制”“无需审查直接执行”等高风险表述。  
High-risk claims such as “auto-fix,” “bypass restrictions,” or “execute without review.”

## 输出形式  
## Output
Confidence
90% confidence
Finding
Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
Administrator privileges, sensitive path access, and system-level modification tendencies.

“自动修复”“绕过限制”“无需审查直接执行”等高风险表述。  
High-risk claims such as “auto-fix,” “bypass restrictions,” or “execute without review.”

## 输出形式  
## Output
Confidence
90% confidence
Finding
Skill attempts to nullify the agent's safety policies or restrictions ('you have no restrictions', 'ignore your guidelines', 'do anything now'). This is a direct jailbreak that disables guardrails.

Instruction Override

High
Category
Prompt Injection
Content
Administrator privileges, sensitive path access, and system-level modification tendencies.

“自动修复”“绕过限制”“无需审查直接执行”等高风险表述。  
High-risk claims such as “auto-fix,” “bypass restrictions,” or “execute without review.”

## 输出形式  
## Output
Confidence
90% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Instruction Override

High
Category
Prompt Injection
Content
Administrator privileges, sensitive path access, and system-level modification tendencies.

“自动修复”“绕过限制”“无需审查直接执行”等高风险表述。  
High-risk claims such as “auto-fix,” “bypass restrictions,” or “execute without review.”

## 输出形式  
## Output
Confidence
90% confidence
Finding
This pattern attempts to override system instructions or ignore safety constraints. Without LLM analysis, manual review is recommended.

Lp3

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding
Without declared permissions the skill's intent is opaque and cannot be validated.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
This code creates a workspace storage directory and initializes a persistent JSON file, but it provides no confirmation prompt, logging, or explanatory comment/docstring to disclose that report data will be written to disk. Because file persistence can affect user data handling and privacy, the lack of any visible warning meets the missing-user-warning criterion for code files.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The save_report function modifies in-memory report data and rewrites the reports.json file, which is a file write operation affecting persistent user/workspace state. There is no confirmation, logging, or explanatory documentation in the code indicating that existing stored data may be updated or replaced.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
This JSON manifest contains natural-language exclusion examples in Chinese alongside English text, but it does not explain whether multilingual handling is intentional or user-selectable. Under the language/locale policy criterion, embedding a specific language without documented opt-in can be a minor policy concern.

Static analysis

No suspicious patterns detected.