Back to skill

Security audit

Clawditor

Security checks for vulnerabilities and agentic risk

Overview

This audit skill is mostly purpose-aligned, but it can copy sensitive memory or log snippets into report files and can be directed to write reports outside the intended workspace.

Review this skill before installing if your workspaces contain secrets, private logs, or sensitive memory. Run it only on workspaces you are comfortable auditing, keep output under a controlled eval directory, inspect generated JSON/Markdown before sharing or committing it, and avoid using overwrite or broad log scanning unless you understand what files may be copied into reports.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/log_scan.py:65
Finding
Unredacted Sensitive Log Content May Be Persisted in Audit Artifacts## Vulnerability Details **File Location**: `scripts/log_scan.py:65-78`, with persistence at `scripts/run_audit.py:70` **Vulnerability Type**: Plaintext sensitive-data exposure **Risk Level**: Medium ### Vulnerable Code ```python try: with f.open("r", errors="ignore") as fh: hits = [] for i, line in enumerate(fh): if i >= args.max_lines: break for regex, label in PATTERNS: if regex.search(line): hits.append({ "label": label, "line": i + 1, "text": line.strip()[:200] }) if hits: results.append({"file": str(f), "hits": hits}) except OSError: continue ``` The resulting data is written without further sanitization: ```python write_json(out_dir / "log_scan.json", log_scan) ``` ### Technical Analysis The log scanner stores the first 200 characters of every line matching terms such as `ERROR`, `Exception`, `Traceback`, `failed`, `timeout`, or `retry`. It does not detect or redact authorization headers, API keys, access tokens, passwords, URL credentials, connection strings, session identifiers, or personal information. Operational error messages frequently include request parameters, configuration values, authentication data, or serialized exceptions. Consequently, the generated `eval/log_scan.json` can contain plaintext copies of sensitive data. This behavior also conflicts with the secret-handling rules in `SKILL.md`, which state that only the presence and path of keys or tokens should be reported. ### Attack Path 1. A workspace log records a sensitive value on a line containing one of the configured failure keywords. 2. The Skill scans that log during an audit. 3. `log_scan.py` copies up to 200 characters of the matching line without redaction. 4. `run_audit.py` serializes the cap ...[truncated 603 chars]
Remediation
## Remediation Suggestions - Apply centralized redaction before any log text is stored or printed. - Redact authorization headers, bearer tokens, API keys, passwords, cookies, private keys, URL user information, database connection strings, and known credential formats. - Prefer storing only the file path, line number, matched label, and a sanitized message. - Replace sensitive values with stable placeholders such as `[REDACTED_TOKEN]`. - Add tests containing representative secrets to verify that neither JSON nor console output contains the original values. - Consider making raw snippets opt-in and displaying an explicit warning when enabled.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/memory_dupes.py:59
Finding
Unredacted Memory Snippets May Be Copied into Duplicate-Analysis Reports## Vulnerability Details **File Location**: `scripts/memory_dupes.py:59-66`, with persistence at `scripts/run_audit.py:69` **Vulnerability Type**: Plaintext sensitive-data exposure **Risk Level**: Medium ### Vulnerable Code ```python if score >= args.threshold: dup_pairs.append({ "a": { "file": a["file"], "index": a["index"], "snippet": a["text"][:160] }, "b": { "file": b["file"], "index": b["index"], "snippet": b["text"][:160] }, "score": round(score, 3), }) ``` The snippets are then persisted without redaction: ```python write_json(out_dir / "memory_dupes.json", memory_dupes) ``` ### Technical Analysis When two memory paragraphs meet the similarity threshold, the report embeds the first 160 characters of each paragraph verbatim. No secret detection, content classification, or redaction is applied. Agent memory may contain tokens, private project details, personal information, internal URLs, or other confidential facts. If such content occurs in sufficiently similar paragraphs, it is duplicated into `eval/memory_dupes.json`. This is inconsistent with the Skill's stated policy against including secrets in report snippets. ### Attack Path 1. Sensitive content is present in two identical or near-duplicate Markdown paragraphs under `memory/`. 2. The paragraphs satisfy the configured length and similarity thresholds. 3. `memory_dupes.py` copies the first 160 characters of both paragraphs into its result. 4. `run_audit.py` writes that result to `eval/memory_dupes.json`. 5. Distribution or storage of the evaluation report discloses the copied content to recipients who may not have had access to the original memory files. ### Impact Assessment This issue does not directly grant local code execution or elevated system privileges. Its impact is confidentiality loss within t ...[truncated 244 chars]
Remediation
## Remediation Suggestions - Run all memory previews through the same centralized redaction layer used for log output. - Prefer reporting paragraph hashes, file locations, paragraph indexes, lengths, and similarity scores instead of raw text. - If previews are necessary, generate sanitized excerpts only after detecting credential and personal-data patterns. - Add a configuration option to disable snippets, with snippets disabled by default. - Add regression tests confirming that representative tokens, passwords, connection strings, and private data never appear in generated reports.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run_audit.py:50
Finding
Unconfined Output Path Allows Writes Outside the Audited Workspace## Vulnerability Details **File Location**: `scripts/run_audit.py:50-60`, with file writes at `scripts/run_audit.py:69-72` and `scripts/run_audit.py:124-131` **Vulnerability Type**: Path traversal and arbitrary-location file write **Risk Level**: Medium ### Vulnerable Code ```python parser.add_argument( "--out", default="eval", help="Output directory under workspace" ) parser.add_argument( "--overwrite", action="store_true", help="Overwrite draft markdown/json templates" ) args = parser.parse_args() root = Path(args.path).resolve() out_dir = root / args.out out_dir.mkdir(parents=True, exist_ok=True) ``` The unvalidated directory is subsequently used for writes: ```python write_json(out_dir / "inventory.json", inventory) write_json(out_dir / "memory_dupes.json", memory_dupes) write_json(out_dir / "log_scan.json", log_scan) write_json(out_dir / "git_stats.json", git_stats) write_if_missing(out_dir / "exec_summary.md", exec_summary, args.overwrite) write_if_missing(out_dir / "scorecard.md", scorecard, args.overwrite) if (out_dir / "latest_report.json").exists() and not args.overwrite: pass else: write_json(out_dir / "latest_report.json", latest_report) ``` ### Technical Analysis Although `--out` is documented as a directory under the workspace, the code does not enforce that boundary. An absolute `Path` operand replaces the workspace path when combined with `root`, while relative paths containing `..` can traverse outside it. The implementation also does not reject a symlinked output directory that resolves elsewhere. The Skill creates the selected directory and writes several predictable filenames. When `--overwrite` is supplied, existing Markdown and JSON report files can be replaced. The writes use generated report content rather than attacker-selected arbitrary bytes, which limits but does not eliminate the impact. ### Attack Path 1. An attacke ...[truncated 974 chars]
Remediation
## Remediation Suggestions - Reject absolute values for `--out`. - Resolve the candidate output path and verify that it remains under the resolved workspace root: ```python if Path(args.out).is_absolute(): parser.error("--out must be relative to the workspace") root = Path(args.path).resolve() out_dir = (root / args.out).resolve() try: out_dir.relative_to(root) except ValueError: parser.error("--out must remain inside the workspace") ``` - Detect and reject symlink components or use safe directory/file-opening primitives that prevent symlink traversal. - Retain non-overwriting behavior by default and require explicit confirmation or a narrowly scoped flag before replacing existing files. - Validate each final destination immediately before writing to reduce time-of-check/time-of-use risk. - Add tests for absolute paths, `../` traversal, nested traversal, and symlink-based escapes.
Vulnerability Patterns
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description promises a broad auditing/evaluation skill for an OpenClaw workspace, including scanning multiple resource types and writing standardized report artifacts. The actual code chunk only collects basic git repository statistics and prints them or emits JSON. While git inspection could be a supporting component of a larger audit system, this chunk by itself does not implement the declared primary behavior, outputs, or scope. Therefore the description materially overstates what this code actually does.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The description claims a comprehensive audit skill for an OpenClaw agent workspace with multiple output artifacts and broader analysis domains. The actual code only implements near-duplicate paragraph detection for markdown files in a memory directory. While this could support a memory-quality review, it is only one small subfunction and lacks the core declared behaviors and outputs. Therefore the declared description materially overstates and misrepresents the code chunk’s actual purpose and capabilities.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The declared description presents a full auditing and report-generation skill for an OpenClaw workspace, including scanning various resources and producing multiple evaluation artifacts. The actual code does not perform auditing, scoring, patching, workspace scanning, or report generation. It only validates the structure of an already-existing latest_report.json file. While this could be a supporting utility within such a skill, the supplied code chunk's actual purpose is materially narrower and different from the declared primary purpose, so this is a mismatch.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The description promises a higher-level auditing and reporting capability for an OpenClaw agent workspace, including scoring, summaries, JSON reports, and patches based on review of memory/logs/configs/git/artifacts. The actual code only walks a directory tree, skips some common folders, gathers file sizes, aggregates directory statistics, and prints a tree plus largest files. While this could be a supporting utility for a larger audit workflow, on its own it does not implement the declared primary behavior or outputs. Therefore the description materially overstates what this code chunk actually does.

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill explicitly instructs use of file reads, file writes, and helper scripts, but it declares no explicit tool scope or permission boundaries. In practice, this increases the chance an agent will execute the audit with broader-than-necessary filesystem or shell access, making accidental overreach, unsafe script execution, or unintended workspace modification more likely.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The skill mandates writing multiple files under eval/ and even creating or refactoring memory files, but it does not require confirmation before modifying the target workspace. In an auditing context, silent writes can overwrite user content, taint evidence, alter repositories under review, or introduce unreviewed patches into sensitive memory/documentation areas.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run(cmd, cwd):
    try:
        out = subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.DEVNULL)
        return out.decode().strip()
    except subprocess.CalledProcessError:
        return ""
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_json(script: str, args, cwd: Path):
    cmd = [sys.executable, str(HERE / script), *args, "--json"]
    proc = subprocess.run(cmd, cwd=str(cwd), capture_output=True, text=True)
    if proc.returncode != 0:
        return {
            "error": "command_failed",
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Static analysis

No suspicious patterns detected.