Back to skill

Security audit

OpenClaw Security Scanner

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent local security scanner, but its secret-scanning output can disclose real credentials into terminal or CI logs.

Review before installing or using in CI. Use it only on directories you intend to scan, avoid running secrets --dir . on workspaces with real credentials, and do not publish or retain its output until secret redaction is fixed. Treat any credentials printed by this version as exposed and rotate them.

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

Error
Location
scripts/main.py:153
Finding
Detected secrets may be disclosed through terminal and CI output<![CDATA[ ## Vulnerability Details **File Location**: `scripts/main.py`, lines 153–160 and 267–275 **Vulnerability Type**: Insufficient masking of sensitive information before output **Risk Level**: High ### Vulnerable Code ```python for i, line in enumerate(lines, 1): for pattern, secret_type in self.PATTERNS: if re.search(pattern, line, re.IGNORECASE): # Mask the secret masked = re.sub(r'["\'][^"\']{10,}["\']', '"***MASKED***"', line.strip()) findings.append({ 'line': i, 'type': secret_type, 'content': masked, 'severity': 'critical' }) ``` ```python for filepath in dirpath.rglob('*'): if filepath.is_file() and filepath.stat().st_size < 1024 * 1024: # Skip large files scanned += 1 secrets = detector.scan_file(filepath) if secrets: total_secrets += len(secrets) print(f"\n🔴 {filepath}") for secret in secrets: print(f" Line {secret['line']}: {secret['type']}") print(f" {secret['content']}") ``` ### Technical Analysis The secret detector stores and prints the source line containing each detected credential. Before doing so, it attempts to sanitize the line with a separate regular expression that only masks values enclosed in matching single or double quotation marks and containing at least ten characters: ```python re.sub(r'["\'][^"\']{10,}["\']', '"***MASKED***"', line.strip()) ``` This masking expression is not tied to the regular expression that detected the secret. Several supported secret formats can be present without quotation marks, including AWS access key IDs, GitHub personal access tokens, API keys, and credential-bearing database URLs. Such values match the detection patterns but do not match the masking pattern, so the original credential remains in `secret['content']` and is printed verbatim. Even when a value is quoted, ...[truncated 2068 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not print the source line containing a detected secret. By default, report only: - Relative file path - Line number - Secret type - Remediation guidance 2. If a preview is operationally necessary, redact the exact span matched by the detection expression rather than applying an unrelated masking expression to the entire line: ```python match = re.search(pattern, line, re.IGNORECASE) if match: masked_line = ( line[:match.start()] + "***REDACTED***" + line[match.end():] ) ``` 3. Prefer omitting previews entirely because surrounding text may contain additional credentials or sensitive information not covered by the detector's patterns. 4. Ensure CI systems do not retain historical output produced by vulnerable versions. Restrict access to existing logs and remove affected artifacts where supported. 5. Treat credentials previously printed by this implementation as potentially compromised. Rotate or revoke them and review the relevant service audit logs for unauthorized use. 6. Add regression tests covering quoted and unquoted AWS keys, GitHub tokens, API keys, database URLs, lines containing multiple credentials, and credentials embedded in assignment or configuration syntax. Tests should assert that the original secret never appears in output. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (9)

Credential Access

High
Category
Privilege Escalation
Content
Scanned: 45 files
Secrets found: 1

🔴 .env (line 3):
   AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
   
   Type: AWS Secret Access Key
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Anti-Refusal Statement

High
Category
Anti-Refusal
Content
| Path traversal | 🔴 Critical | CWE-22 |
| Insecure crypto | 🟡 Medium | CWE-327 |
| Weak random | 🟡 Medium | CWE-338 |
| Debug mode enabled | 🟡 Medium | CWE-489 |

### 密钥模式
Confidence
75% 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
return issues

    def _check_debug_mode(self, tree: ast.AST, lines: list, filepath: Path) -> list:
        """Check for debug mode enabled"""
        issues = []

        for node in ast.walk(tree):
Confidence
75% 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
if isinstance(node.value, ast.Constant) and node.value.value == True:
                            issues.append({
                                'line': node.lineno,
                                'message': 'DEBUG mode enabled',
                                'severity': 'medium',
                                'type': 'debug-mode',
                                'cwe': 'CWE-489',
Confidence
75% 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.

Credential Access

High
Category
Privilege Escalation
Content
PATTERNS = [
        (r'AKIA[0-9A-Z]{16}', 'AWS Access Key ID'),
        (r'aws_secret_access_key\s*=\s*["\']?[A-Za-z0-9/+=]{40}["\']?', 'AWS Secret Key'),
        (r'ghp_[A-Za-z0-9]{36}', 'GitHub Personal Access Token'),
        (r'sk-[A-Za-z0-9]{20,}', 'OpenAI/Stripe API Key'),
        (r'private[_-]?key\s*[=:]\s*["\']?-----BEGIN', 'Private Key'),
        (r'database[_-]?url\s*[=:]\s*["\']?\w+://[^:]+:[^@]+@', 'Database URL with credentials'),
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
91% confidence
Finding
The skill documentation advertises command execution and file scanning capabilities via `python3 scripts/main.py` and directory/file inputs, but it does not declare any explicit tool scope such as allowed tools or permissions. In an agent setting, missing scope declarations can lead to overbroad access assumptions and unsafe invocation of shell or file-read capabilities beyond what users expect.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The skill body and feature descriptions are presented in Chinese, while the file does not state that the tool is region-specific or give users a language/locale option. This creates a natural-language policy concern because it effectively constrains the skill to a specific language without user opt-in.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The manifest says the skill 'checks dependencies' and provides vulnerability detection, but the deps command only reads a requirements file, counts packages, and prints advice to use external tools. It does not actually analyze dependency vulnerabilities or perform dependency security checks itself, creating a mismatch between the described capability and implemented behavior.

Description-Behavior Mismatch

Low
Confidence
89% confidence
Finding
The command-line interface suggests support for '--package-json' in the deps command, but the implementation only handles '--requirements' and otherwise prints a generic hint. This overstates actual behavior and can mislead users about what dependency checking the skill performs.

Static analysis

No suspicious patterns detected.