Back to skill

Security audit

OpenClaw Security Analysis

Security checks for vulnerabilities and agentic risk

Overview

This security-scanning skill is mostly purpose-aligned, but it can expose scanned secrets in output and imports optional code from outside the skill package.

Review before installing. Use the scanner only on directories you intend to expose to its output, avoid sending its logs to shared CI until redaction is fixed, and treat dependency results as informational rather than a real vulnerability audit. The optional C support import should be packaged inside the skill or integrity-checked before trusting it.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:246
Finding

Detected secrets can be disclosed through incomplete output redaction

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py, lines 210-215, 246, and 372
Vulnerability Type: Incomplete sensitive-data redaction
Risk Level: High

Vulnerable Code

python
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'),
]
python
# Mask the secret
masked = re.sub(r'["\'][^"\']{10,}["\']', '"***MASKED***"', line.strip())
findings.append({
    'line': i,
    'type': secret_type,
    'content': masked,
    'severity': 'critical'
})
python
for secret in secrets:
    print(f"   Line {secret['line']}: {secret['type']}")
    print(f"   {secret['content']}")

Technical Analysis

The detector recognizes several credentials that do not need to be enclosed in quotation marks, including AWS access key IDs, GitHub personal access tokens, OpenAI or Stripe keys, unquoted AWS secret keys, and credentials embedded in database URLs.

The redaction expression only replaces a sequence of at least ten characters surrounded by matching quote-like delimiters. Consequently, an unquoted secret can be successfully detected but remain unchanged in secret['content']. The program subsequently prints that content directly.

This is especially dangerous for a security scanner because its output is likely to be retained in CI logs, terminal recordings, support bundles, or audit artifacts.

Attack Path

  1. A repository or scanned directory contains a credential in a supported but unquoted format, such as an unquoted ghp_... token or AWS access key.
  2. A user or CI job invokes `python3 script ...[truncated 1025 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not print source lines containing detected credentials. Report only the file path, line number, credential type, and a non-sensitive fingerprint if correlation is required.
  • If a preview is necessary, redact the exact match produced by the credential-specific pattern rather than searching for an independently quoted value.
  • Use re.sub() with the active detection pattern or preserve the match span and replace that exact character range with ***MASKED***.
  • For database URLs, parse and replace the password and other sensitive components before rendering any output.
  • Avoid retaining plaintext secret-bearing lines in the finding structure.
  • Add automated tests covering quoted and unquoted variants of every supported credential format.
  • Configure CI systems to restrict access to historical scanner logs and remove existing logs that may contain exposed credentials.
  • Rotate any real credentials that have already appeared in scanner output.

T07 · Tool Hijacking and Spoofing

Warning
Location
scripts/main.py:13
Finding

Untrusted Python module can be executed from outside the Skill package

Content
View full analysis

Vulnerability Details

File Location: scripts/main.py, lines 13-20
Vulnerability Type: External module search-path hijacking
Risk Level: Medium

Vulnerable Code

python
# Import C support library
c_support_path = Path(__file__).parent.parent.parent / 'c-support' / 'lib'
if c_support_path.exists():
    sys.path.insert(0, str(c_support_path))
    try:
        from c_security_rules import CSecurityChecker, CSecurityRules
        C_SUPPORT_AVAILABLE = True
    except ImportError:
        C_SUPPORT_AVAILABLE = False
else:
    C_SUPPORT_AVAILABLE = False

Technical Analysis

The program constructs a path outside the audited Skill directory and places it at index zero of sys.path. Python then imports c_security_rules from that preferred search location. Importing a Python module executes its module-level code immediately, before command-line processing or scanning begins.

The referenced component is not included in the audited project. The code verifies only that the directory exists; it does not verify the module's ownership, permissions, origin, version, or cryptographic integrity. If an attacker can create or replace c_security_rules.py in that neighboring directory, the legitimate scanner invocation becomes an arbitrary code-execution mechanism.

Catching ImportError does not mitigate the issue because malicious module-level statements execute during the attempted import. Other exceptions are also not caught by this block.

Attack Path

  1. An attacker gains write access to the expected neighboring c-support/lib directory, or supplies the Skill inside a parent directory structure containing an attacker-controlled c-support/lib.
  2. The attacker creates c-support/lib/c_security_rules.py with malicious module-level Python code.
  3. A victim invokes any command in scripts/main.py; a C scan is not required because the import occurs during program startup.
  4. The program ...[truncated 858 chars]
Remediation
View remediation

Remediation Suggestions

  • Do not prepend an externally located directory to sys.path.
  • Package the C support code inside the Skill and import it through a package-relative import.
  • Alternatively, install the support library as a pinned and integrity-verified dependency in an isolated environment.
  • If optional dynamic loading is unavoidable, resolve the exact expected file and verify its owner, permissions, trusted location, and cryptographic hash before loading it.
  • Reject directories or module files writable by untrusted users.
  • Avoid relying on ambient parent-directory layouts to locate executable dependencies.
  • Add tests confirming that neighboring files cannot shadow the expected support module.
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 (10)

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The documentation includes what appears to be an AWS secret access key in a sample output. Even if this specific value is an example or non-live placeholder, embedding realistic secret formats in documentation can train unsafe handling patterns, trigger accidental reuse, and normalize inclusion of credentials in repository content. In a security-analysis skill, this is especially sensitive because users may copy examples directly or assume such exposure is acceptable.

Content

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

md
Scanned: 45 files
Secrets found: 1

🔴 .env (line 3):
   AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
   
   Type: AWS Secret Access Key

Anti-Refusal Statement

High
Category
Anti-Refusal
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.

Content

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

md
| Path traversal | 🔴 Critical | CWE-22 |
| Insecure crypto | 🟡 Medium | CWE-327 |
| Weak random | 🟡 Medium | CWE-338 |
| Debug mode enabled | 🟡 Medium | CWE-489 |

### 密钥模式

Anti-Refusal Statement

High
Category
Anti-Refusal
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.

Content

Scanner excerpt · scripts/main.py (reported line 176)May include surrounding context.

python
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):

Anti-Refusal Statement

High
Category
Anti-Refusal
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.

Content

Scanner excerpt · scripts/main.py (reported line 186)May include surrounding context.

python
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',

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/main.py (reported line 212)May include surrounding context.

python
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'),

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/main.py (reported line 364)May include surrounding context.

python
for filepath in dirpath.rglob('*'):
        if filepath.is_file() and filepath.stat().st_size < 1024 * 1024:  # Skip large files
            # Check relevant file types
            if filepath.suffix in ['.py', '.c', '.h', '.js', '.ts', '.json', '.yml', '.yaml', '.env']:
                scanned += 1
                secrets = detector.scan_file(filepath)
                if secrets:

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documents shell-based commands and file access behavior but does not declare any tool scope such as permissions or allowed-tools. This creates an authorization ambiguity where an agent may invoke filesystem reads and shell execution more broadly than intended, increasing the chance of unsafe command execution or overbroad file access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

This markdown mixes English headings with core descriptive and usage content in Chinese, but does not indicate that the skill is intentionally region-specific or provide an opt-in language choice. Under the policy, forcing a specific language or locale without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill metadata and command help imply dependency vulnerability scanning, but the implementation only parses requirements and prints advice to use external tools. This creates a false sense of security: users may believe dependencies were checked when no vulnerability assessment actually occurred.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The dependency-check functionality is documented as a check, but operationally it only enumerates packages and recommends third-party tools. In a security skill, this mismatch is risky because it can mislead operators into skipping real dependency auditing.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.