Back to skill

Security audit

Log Scrubber

Security checks for vulnerabilities and agentic risk

Overview

The skill is a local log and memory secret scrubber, but it can leave the original secrets in backup files and can follow symlinks outside the intended workspace.

Install only if you are comfortable with a local script recursively reading and modifying OpenClaw memory and log files. Run dry-run first, inspect the file list, and be aware that applying changes may create .bak files containing the original secrets; remove or protect those backups and avoid running it in workspaces where untrusted users or tools can create symlinks under logs or memory.

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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/scrub.py:66
Finding
Unredacted Secrets Persist in Plaintext Backup Files## Vulnerability Details **File Location**: `scripts/scrub.py`, lines 66-69 **Vulnerability Type**: Plaintext retention of sensitive data **Risk Level**: High ### Vulnerable Code ```python # Create backup shutil.copy2(path, path + ".bak") with open(path, 'w', encoding='utf-8') as f: f.write(new_content) ``` The script copies each original file to a `.bak` file before writing the redacted version. Because the backup is created from the original content, it retains every API key, password, token, or other secret that the scrubber detected. Files ending in `.bak` are explicitly excluded from subsequent scans at line 48: ```python if f.endswith('.bak'): continue ``` Consequently, the sensitive backup is neither redacted nor reported during future executions. This conflicts with the stated security objective of preventing secrets from remaining in plaintext memory and log files. ### Attack Path 1. A target file under `memory`, `logs`, or `MEMORY.md` contains a credential matching one of the configured patterns. 2. A user runs the scrubber without `--dry-run`. 3. The script copies the complete original file, including its credentials, to `<filename>.bak`. 4. The original file is overwritten with its redacted version. 5. Future scans skip the `.bak` file. 6. A local user, malicious process, backup service, synchronization process, or later workspace export accesses the backup and recovers the original credential. ### Impact Assessment Successfully detected credentials remain recoverable in plaintext. Anyone who can read the workspace or its archived copies may obtain API keys, tokens, passwords, and other sensitive information. The affected scope includes every modified file beneath `/root/.openclaw/workspace/memory`, `/root/.openclaw/workspace/logs`, and the workspace `MEMORY.md` file. The vulnerability does not itself grant new operating-system privileges, but exposed credentials may grant access to e ...[truncated 95 chars]
Remediation
## Remediation Suggestions - Do not create unredacted backups by default. - Make backup creation an explicit opt-in operation with a clear warning that backups may contain secrets. - If recovery copies are required, encrypt them using a key stored outside the workspace. - Store backups outside directories that may be synchronized, indexed, exported, or processed as logs. - Apply restrictive permissions, such as owner-only read and write access, when creating backup files. - Establish and enforce a short retention period followed by secure deletion. - Detect existing `.bak` files and warn users that they may contain unredacted credentials. - Prefer an atomic replacement strategy using a securely created temporary file containing only redacted content.

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/scrub.py:39
Finding
Broad Recursive Access to Agent Memory and Log Content## Vulnerability Details **File Location**: `scripts/scrub.py`, lines 39-57 **Vulnerability Type**: Excessive file access and insufficient least-privilege restrictions **Risk Level**: Medium ### Vulnerable Code ```python base_dir = "/root/.openclaw/workspace" target_dirs = ["memory", "logs"] extra_files = ["MEMORY.md"] for d in target_dirs: full_path = os.path.join(base_dir, d) if not os.path.exists(full_path): continue for root, _, files in os.walk(full_path): for f in files: if f.endswith('.bak'): continue path = os.path.join(root, f) process_file(path, args.dry_run) for f in extra_files: path = os.path.join(base_dir, f) if os.path.exists(path): process_file(path, args.dry_run) ``` ### Technical Analysis The script recursively processes every non-`.bak` file beneath the workspace `memory` and `logs` directories, regardless of file type, ownership, purpose, size, or sensitivity. It also processes the global `MEMORY.md` file. This access is consistent with the Skill's documented purpose, and no network exfiltration was identified. Nevertheless, the implementation does not enforce least privilege. It lacks an explicit target allowlist, expected-extension filtering, regular-file validation, file-size limits, and per-run user confirmation of the files that will be modified. Broad access also increases the consequences of false-positive regular-expression matches. Unrelated files can be rewritten merely because their content resembles a credential assignment. ### Attack Path 1. An attacker or another workspace component places a file containing crafted content in the `memory` or `logs` directory tree. 2. A privileged user invokes the scrubber. 3. Recursive traversal automatically selects the file without explicit approval. 4. The script reads its complete contents. 5. If content matches a redaction pattern, the scr ...[truncated 788 chars]
Remediation
## Remediation Suggestions - Require users to supply or explicitly approve target paths. - Restrict processing to an allowlist of expected text file extensions. - Verify that each target is a regular file before reading or modifying it. - Add configurable file-size limits to avoid processing arbitrary or unexpectedly large files. - Present a file manifest in dry-run mode and require confirmation before modification. - Permit users to exclude sensitive subdirectories and files. - Run the Skill under a dedicated, minimally privileged account rather than as `root`. - Log file-selection decisions without logging file contents or detected secrets.

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/scrub.py:47
Finding
Symbolic Links Permit Reads and Writes Outside the Intended Workspace## Vulnerability Details **File Location**: `scripts/scrub.py`, lines 47-69 **Vulnerability Type**: Symlink traversal and arbitrary file modification **Risk Level**: High ### Vulnerable Code ```python for root, _, files in os.walk(full_path): for f in files: if f.endswith('.bak'): continue path = os.path.join(root, f) process_file(path, args.dry_run) def process_file(path, dry_run): try: with open(path, 'r', encoding='utf-8') as f: content = f.read() new_content, changed = scrub_content(content) if changed: if dry_run: print(f"[DRY-RUN] Would scrub: {path}") else: # Create backup shutil.copy2(path, path + ".bak") with open(path, 'w', encoding='utf-8') as f: f.write(new_content) ``` ### Technical Analysis Files discovered through `os.walk` are opened without checking whether they are symbolic links. The script also does not resolve each path and verify that its canonical destination remains beneath `/root/.openclaw/workspace/memory` or `/root/.openclaw/workspace/logs`. Python's `open()` follows symbolic links. Therefore, a symlink located in a scanned directory can point to a file outside the workspace. If the destination is readable by the user running the script, its contents will be read. If it is writable and contains text matching a configured pattern, the destination can be overwritten with redacted content. `shutil.copy2(path, path + ".bak")` also reads through the source symlink and stores the external file's original contents in a backup located next to the symlink path. This can copy sensitive external data into the workspace. ### Attack Path 1. An attacker obtains permission to create a file or symbolic link under the workspace `memory` or `logs` directory. 2. The attacker creates a symlink such as `logs/tar ...[truncated 1582 chars]
Remediation
## Remediation Suggestions - Reject symbolic links by checking each discovered path with `os.lstat()` or `os.path.islink()` before opening it. - Require every target to be a regular file. - Resolve paths using `os.path.realpath()` and verify with `os.path.commonpath()` that the resolved destination remains under the approved root. - Repeat validation immediately before both reading and writing to reduce time-of-check/time-of-use race exposure. - Use directory file descriptors and no-follow semantics, such as `O_NOFOLLOW` where supported, for stronger protection. - Avoid running the scrubber as `root`; use an account restricted to the intended workspace. - Create replacement files securely inside the validated directory and perform an atomic rename only after validating the destination. - Add tests covering symlinks to files both inside and outside the authorized workspace.
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (1)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill advertises local scanning and in-place redaction across workspace logs and memory files, which requires broad file read/write access, but it does not declare any explicit tool scope or permissions boundaries. This creates a transparency and least-privilege problem: the agent may exercise filesystem capabilities beyond what users or platform policy can easily audit, increasing risk of unintended modification, overbroad access, or abuse by altered script contents.

Static analysis

No suspicious patterns detected.