Back to skill

Security audit

OpenClaw Memory Audit

Security checks for vulnerabilities and agentic risk

Overview

This is a disclosed local secret-scanning skill with no evidence of exfiltration, persistence, or destructive behavior, but users should understand its scan boundaries and limitations.

Install only if you are comfortable with the agent reading files in the selected workspace to look for secrets. Run it against the intended workspace path, treat clean results as best-effort rather than complete proof, and verify separately that any memory logs and weekly audit schedule are actually covered.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/scan_secrets.py:35
Finding

Unrestricted Filesystem Scanning Outside the Intended Workspace

Content
View full analysis

Vulnerability Details

File Location: scripts/scan_secrets.py, lines 35-49 and 64-65
Vulnerability Type: Unrestricted filesystem traversal
Risk Level: Medium

Vulnerable Code

python
def main(root_dir):
    all_findings = []
    for root, dirs, files in os.walk(root_dir):
        # Filter directories
        dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS]
        
        for file in files:
            if file in EXCLUDE_FILES or file.endswith((".png", ".jpg", ".jpeg", ".gif", ".pdf", ".zip", ".skill")):
                continue
            
            file_path = os.path.join(root, file)
            findings = scan_file(file_path)
            all_findings.extend(findings)
python
if __name__ == "__main__":
    target = sys.argv[1] if len(sys.argv) > 1 else "."
    main(target)

Technical Analysis

The script accepts an arbitrary filesystem path from its first command-line argument and recursively opens files beneath that path. It does not canonicalize the target, verify that it is within the authorized OpenClaw workspace, or require explicit approval before scanning a location outside that workspace.

The implementation also does not validate each resolved file path before opening it. Consequently, a caller can select broad locations such as the filesystem root, a home directory, or a credential directory. File symlinks encountered during traversal may also reference files outside the nominal scan root.

Although detected values are masked and the reviewed code contains no network exfiltration mechanism, the output still reveals sensitive metadata, including filenames, line numbers, credential types, and fragments of matched values.

Attack Path

  1. An attacker, malicious automation, or injected instruction causes the Skill to invoke the script with an overly broad or sensitive path.
  2. The command-line argument is assigned directly to target without ...[truncated 1102 chars]
Remediation
View remediation

Remediation Suggestions

  1. Resolve both the authorized workspace and requested target with os.path.realpath().
  2. Reject any target that is not equal to or contained within the authorized workspace, using os.path.commonpath() rather than unsafe string-prefix comparisons.
  3. Require explicit user authorization before scanning any location outside the default workspace.
  4. Reject symbolic-link files, or resolve every candidate file and verify that its canonical path remains inside the approved boundary before opening it.
  5. Consider accepting only workspace-relative paths rather than unrestricted absolute paths.
  6. Document the precise scan boundary and report the canonical target before scanning.
  7. Run the scanner with a minimally privileged operating-system account.

Example boundary validation:

python
workspace = os.path.realpath(os.environ["OPENCLAW_WORKSPACE"])
target = os.path.realpath(requested_target)

if os.path.commonpath([workspace, target]) != workspace:
    raise ValueError("Scan target is outside the authorized workspace")

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/scan_secrets.py:25
Finding

Suppressed File-Read Errors Can Produce False-Negative Audit Results

Content
View full analysis

Vulnerability Details

File Location: scripts/scan_secrets.py, lines 25-37 and 52-53
Vulnerability Type: Silent error handling and misleading success reporting
Risk Level: Medium

Vulnerable Code

python
def scan_file(file_path):
    findings = []
    try:
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            for line_num, line in enumerate(f, 1):
                for name, pattern in PATTERNS.items():
                    matches = re.finditer(pattern, line)
                    for match in matches:
                        # Mask the finding
                        val = match.group(0)
                        masked = val[:6] + "..." + val[-4:] if len(val) > 10 else "***"
                        findings.append({
                            "file": file_path,
                            "line": line_num,
                            "type": name,
                            "masked": masked
                        })
    except Exception as e:
        pass
    return findings
python
if not all_findings:
    print("✅ No secrets found in workspace.")

Technical Analysis

scan_file() catches every Exception and discards it without recording that the file was not successfully scanned. Permission errors, file deletion races, unusual filesystem errors, and other I/O failures are therefore indistinguishable from a successful scan that found no credentials.

The aggregate result only checks whether all_findings is empty. It does not check whether every intended file was read successfully. As a result, the script can print the definitive statement No secrets found in workspace even when part or all of the scan failed.

The use of errors='ignore' additionally discards invalid UTF-8 bytes. While this can help process imperfect text files, it can also alter input and cause patterns spanning discarded bytes to be missed.

A

...[truncated 1332 chars]

Remediation
View remediation

Remediation Suggestions

  1. Replace the broad silent handler with explicit handling for expected exceptions such as PermissionError, OSError, and UnicodeError.
  2. Record every failed file along with a sanitized error description.
  3. Track whether the scan completed successfully and never emit an unconditional clean result when errors occurred.
  4. Print separate totals for scanned, skipped, failed, and matched files.
  5. Return a nonzero process exit status when coverage is incomplete so automated workflows can fail safely.
  6. Consider strict UTF-8 decoding first and report decoding failures. If tolerant decoding is required, mark the affected file as incompletely analyzed.
  7. Avoid exposing sensitive exception details beyond what is necessary for remediation.

Example fail-safe result handling:

python
def scan_file(file_path):
    findings = []
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            # Perform matching.
            pass
        return findings, None
    except (PermissionError, OSError, UnicodeError) as exc:
        return findings, f"{type(exc).__name__}: scan incomplete"

# After processing all files:
if scan_errors:
    print(f"Scan incomplete: {len(scan_errors)} file(s) could not be analyzed.")
    sys.exit(2)
elif not all_findings:
    print("No secrets found in the successfully scanned workspace.")
Vulnerability Patterns
  • 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
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (3)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The main behavior—scanning workspace files for possible exposed secrets—matches the core of the description. However, a significant declared feature is missing: the code does not check whether a recurring audit schedule is active and does not recommend a weekly scan if missing. Additionally, the description explicitly mentions scanning memory logs, but the implementation only walks a filesystem tree and scans files generically; there is no dedicated logic for locating or auditing memory logs. Because the description claims capabilities beyond what the code actually does, this is a mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill instructs the agent to scan the workspace and inspect cron state, which implies file-reading and system/tool access, but it does not declare any explicit tool scope or permissions boundary. In an agent environment, missing scope declarations can cause overbroad access, ambiguous enforcement, or accidental use of capabilities beyond what the skill actually needs.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill description promises scanning of workspace and memory logs plus verification of a recurring audit schedule, but the implementation only walks local files and applies regex matching. This mismatch can create a false sense of security: users may rely on the skill to detect leaked secrets in memory logs or confirm ongoing audit coverage when neither check actually exists.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.