Back to skill

Security audit

claude-review

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent review purpose, but it runs an external Claude CLI with weakened permission checks and automatically stores review failures for future use.

Review the exact files or folders before invoking this skill, avoid using it on directories that may contain secrets, and consider disabling or redirecting LESSONS_FILE if you do not want review details retained. Install the Claude CLI only from a trusted source and be aware that reviewed content may be sent to the Claude service.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
review-work.sh:117
Finding
Unrestricted model-assisted file access can expose data outside the review scope<![CDATA[ ## Vulnerability Details **File Location**: `review-work.sh:117-121, 137-155` **Vulnerability Type**: Excessive filesystem permissions and insufficient isolation **Risk Level**: High ### Vulnerable Code ```bash SYSTEM_PROMPT="You are a code and content reviewer. You can ONLY read files — never edit, write, or execute anything. ## How to review 1. Read ALL files at the given path. If it's a folder, read every file in it (skip node_modules, .git, __pycache__, dist, build, .next, vendor, venv, .cache directories). For images, view them. For PDFs, read them. ``` ```bash # User prompt: task-specific info USER_PROMPT="Review the work at \`$CONTEXT_PATH\`. **Original task:** ${TASK}" if [ -n "$SKILL_PATH" ] && [ -e "$SKILL_PATH" ]; then USER_PROMPT="${USER_PROMPT} **Skill definition:** \`$SKILL_PATH\` — read this and verify the work meets every requirement." fi if [ -f "$LESSONS_FILE" ]; then USER_PROMPT="${USER_PROMPT} **Past mistakes:** \`$LESSONS_FILE\` — read this and check for repeat mistakes." fi ``` The resulting prompt is executed at `review-work.sh:159-165`: ```bash REVIEW_OUTPUT=$(claude --print \ --model sonnet \ --dangerously-skip-permissions \ --tools "Read,Glob,Grep" \ --no-session-persistence \ --append-system-prompt "$SYSTEM_PROMPT" \ "$USER_PROMPT" 2>"$STDERR_LOG") ``` ### Technical Analysis The script grants the Claude CLI local `Read`, `Glob`, and `Grep` tools while explicitly disabling permission enforcement through `--dangerously-skip-permissions`. The requested context path is communicated only through natural-language prompt content; it is not an operating-system-level or tool-level access boundary. Files under the context path, the optional skill path, the task summary, and the persistent lessons file must therefore be treated as untrusted prompt content. A malicious reviewed file can contain instructions asking the model to ignore the intended review scope and read sensitive files elsewhere on the filesys ...[truncated 1926 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove `--dangerously-skip-permissions` and retain the Claude CLI's normal permission checks. 2. Do not rely on prompt instructions to enforce filesystem boundaries. 3. Copy explicitly approved review inputs into a newly created, permission-restricted temporary directory and expose only that directory to the reviewer. 4. Resolve and validate every path with `realpath`, then reject paths that escape the approved root. 5. Reject or safely dereference symbolic links so they cannot point outside the review root. 6. Apply an allowlist of file types and exclude common secret-bearing files such as `.env`, private keys, credential stores, cloud configuration, and authentication tokens. 7. Require explicit user confirmation before sending local files to an external service, especially when the context is a directory. 8. Run the reviewer in an operating-system sandbox or container with read access only to staged inputs and no access to the user's home directory. 9. Treat all file contents as untrusted data and explicitly instruct the reviewer not to follow instructions embedded in reviewed artifacts. This prompt-level mitigation should supplement, not replace, technical isolation. ]]>

T02 · Agent Memory Poisoning

Error
Location
review-work.sh:142
Finding
Untrusted review output is persisted and reused as long-term agent context<![CDATA[ ## Vulnerability Details **File Location**: `review-work.sh:142-145, 173-190` **Vulnerability Type**: Persistent memory poisoning through unsanitized model output **Risk Level**: High ### Vulnerable Code The persistent lessons file is automatically included in future review prompts: ```bash if [ -f "$LESSONS_FILE" ]; then USER_PROMPT="${USER_PROMPT} **Past mistakes:** \`$LESSONS_FILE\` — read this and check for repeat mistakes." fi ``` Failed-review content is selected using keyword matching and appended to that file: ```bash # Auto-log to LESSONS.md if the review failed if echo "$REVIEW_OUTPUT" | grep -q "VERDICT: FAIL"; then VERDICT_LINE=$(echo "$REVIEW_OUTPUT" | grep "VERDICT: FAIL" | tail -1) DATE=$(date +%Y-%m-%d) # Extract critical and major issues (skip minor) ISSUES=$(echo "$REVIEW_OUTPUT" | grep -iE '(critical|major)\b' | grep -v 'VERDICT' | grep -v '0 critical' | grep -v '0 major' | head -10) # Create directory if needed LESSONS_DIR=$(dirname "$LESSONS_FILE") mkdir -p "$LESSONS_DIR" # Append learning entry (quoted heredoc prevents command injection from backticks in variables) { echo "" echo "### [$DATE] REVIEW-FAIL: $(basename "$CONTEXT_PATH")" echo "" printf 'TASK: %s\n' "$TASK" printf 'CONTEXT: %s\n' "$CONTEXT_PATH" printf '%s\n' "$VERDICT_LINE" echo "ISSUES:" printf '%s\n' "$ISSUES" echo "" echo "---" } >> "$LESSONS_FILE" fi ``` ### Technical Analysis The review output is influenced by several untrusted sources: - The user-provided task summary - Files under the context path - The optional skill definition - Existing lessons content If the output contains `VERDICT: FAIL`, lines containing the words `critical` or `major` are copied into `LESSONS.md`. This filtering does not validate semantics or distinguish genuine findings from attacker-authored directives. An attacker can induce the model to emit arbitrary imperative text containing one of those keywords. The res ...[truncated 2169 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Stop automatically persisting free-form model output. 2. Require explicit human review and approval before any lesson is added to long-term storage. 3. Replace keyword extraction with a strict structured-output schema containing bounded fields such as identifier, category, factual observation, and approved remediation. 4. Validate parsed fields against length, character, and enumeration constraints; reject imperative instructions and unrecognized fields. 5. Store provenance metadata, including source context, timestamp, model version, and approval status. 6. Treat lessons as quoted reference data rather than instructions. The system prompt should state that lessons cannot modify tool permissions, review scope, or higher-priority rules. 7. Keep lessons project-specific instead of sharing one global file across unrelated reviews. 8. Provide a mechanism to inspect, revoke, and expire lessons. 9. Consider recording only stable issue identifiers and human-authored summaries instead of raw model-generated text. 10. Apply filesystem permissions that prevent untrusted users or projects from modifying the lessons file directly. ]]>

T08 · Insecure Dependencies

Warning
Location
SKILL.md:31
Finding
Documentation recommends globally installing an unpinned executable dependency<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:31-33` **Vulnerability Type**: Unpinned global third-party dependency installation **Risk Level**: Medium ### Vulnerable Code ```markdown ## Prerequisites - `claude` CLI must be installed and available in PATH (`npm install -g @anthropic-ai/claude-code`) - Valid API key configured for Claude CLI ``` ### Technical Analysis The documented installation command retrieves the currently published version of `@anthropic-ai/claude-code` rather than a specific audited release. This makes installation non-reproducible: the same command can install different code at different times. npm packages may execute lifecycle scripts during installation. A global installation also places executable content into globally accessible user or system-level npm locations, depending on npm configuration and the privileges used to run the command. If the package, its dependency chain, the configured registry, or a future release is compromised, following the documented command could execute or install unintended code. The audit found no evidence that the named package is itself malicious. The issue is the unsafe dependency acquisition pattern and absence of version or integrity controls. ### Attack Path 1. A user follows the prerequisite documented in `SKILL.md`. 2. npm resolves the package through the user's configured registry without a version pin. 3. The registry supplies the latest matching package and transitive dependencies at that time. 4. If the package release, dependency chain, account, or registry has been compromised, malicious package content or lifecycle scripts execute during installation. 5. The globally installed executable is subsequently invoked by `review-work.sh` under the user's privileges. ### Impact Assessment A compromised dependency can execute code with the privileges of the user performing installation and can replace or alter the `claude` executable subsequently trusted by the script. ...[truncated 533 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the dependency to a reviewed exact version, for example `@anthropic-ai/claude-code@<audited-version>`. 2. Document the expected official registry and verify that npm is not configured to use an untrusted mirror. 3. Prefer a project-local dependency managed by a lockfile instead of a global installation. 4. Use reproducible installation methods such as `npm ci` with a committed lockfile. 5. Verify package provenance and integrity through registry signatures, checksums, or an internally approved artifact repository. 6. Audit the pinned package and its transitive dependencies before upgrading. 7. Disable lifecycle scripts during installation where operationally possible, then explicitly enable only required setup steps. 8. Do not install with administrative privileges; document that users must not use `sudo` for the package installation. 9. Validate the resolved executable path and expected version before invoking `claude`. ]]>
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (12)

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger list includes broad everyday phrases such as "check your output," "self-review," and "quality check," which can cause the skill to activate in situations the user did not clearly intend. Because activation leads to running an external CLI and potentially reading/writing local files, accidental invocation expands the chance of unintended command execution and data exposure.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill states that failed reviews are automatically logged to LESSONS.md and auto-included in future reviews, but it does not clearly warn the user that task content, mistakes, or possibly sensitive material may be written to disk and persisted across sessions. This creates a privacy and data-governance risk, especially if reviewed artifacts contain secrets, proprietary code, or personal information.

Session Persistence

Medium
Category
Rogue Agent
Content
Review a single file:

```bash
review-work "Write a Python email validator" --context /tmp/email.py
```

Review with skill context (reviewer verifies against skill requirements):
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
## What NOT to Do

- Do NOT ask the user for arguments — you already know what you created and which skill you used
- Do NOT say "review passed" without actually running the command
- Do NOT fabricate review results — the command produces real output
- Do NOT forget `--skill` when a skill was involved in the task
Confidence
91% confidence
Finding
The instruction "Do NOT ask the user for arguments — you already know what you created" encourages the agent to make autonomous decisions about task summary, context paths, and optional skill paths without explicit user confirmation. In this skill, that autonomy matters because it can cause the agent to select broader-than-necessary files or folders for review and pass them to an external CLI, increasing the risk of unintended data exposure or command side effects.

Session Persistence

Medium
Category
Rogue Agent
Content
echo "  --skill <path>        SKILL.md or skill folder used for the task (optional)"
      echo ""
      echo "Examples:"
      echo "  review-work \"Write a Python email validator\" --context /tmp/email.py"
      echo "  review-work \"Write an SEO blog\" --context /tmp/blog.md --skill ~/skills/seo-content-writer/SKILL.md"
      echo "  review-work \"Build a todo app\" --context /tmp/my-app/ --skill ~/skills/fullstack/SKILL.md"
      echo ""
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Skill Enumeration

Medium
Category
Agent Snooping
Content
echo ""
      echo "Examples:"
      echo "  review-work \"Write a Python email validator\" --context /tmp/email.py"
      echo "  review-work \"Write an SEO blog\" --context /tmp/blog.md --skill ~/skills/seo-content-writer/SKILL.md"
      echo "  review-work \"Build a todo app\" --context /tmp/my-app/ --skill ~/skills/fullstack/SKILL.md"
      echo ""
      echo "Environment:"
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
echo ""
      echo "Examples:"
      echo "  review-work \"Write a Python email validator\" --context /tmp/email.py"
      echo "  review-work \"Write an SEO blog\" --context /tmp/blog.md --skill ~/skills/seo-content-writer/SKILL.md"
      echo "  review-work \"Build a todo app\" --context /tmp/my-app/ --skill ~/skills/fullstack/SKILL.md"
      echo ""
      echo "Environment:"
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
echo "Examples:"
      echo "  review-work \"Write a Python email validator\" --context /tmp/email.py"
      echo "  review-work \"Write an SEO blog\" --context /tmp/blog.md --skill ~/skills/seo-content-writer/SKILL.md"
      echo "  review-work \"Build a todo app\" --context /tmp/my-app/ --skill ~/skills/fullstack/SKILL.md"
      echo ""
      echo "Environment:"
      echo "  LESSONS_FILE    Path to lessons file (default: ~/.openclaw/workspace/LESSONS.md)"
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Skill Enumeration

Medium
Category
Agent Snooping
Content
echo "Examples:"
      echo "  review-work \"Write a Python email validator\" --context /tmp/email.py"
      echo "  review-work \"Write an SEO blog\" --context /tmp/blog.md --skill ~/skills/seo-content-writer/SKILL.md"
      echo "  review-work \"Build a todo app\" --context /tmp/my-app/ --skill ~/skills/fullstack/SKILL.md"
      echo ""
      echo "Environment:"
      echo "  LESSONS_FILE    Path to lessons file (default: ~/.openclaw/workspace/LESSONS.md)"
Confidence
80% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The code comments describe the review as using read-only tools, but the claude invocation includes --dangerously-skip-permissions, which weakens safety controls and can permit broader tool behavior if CLI behavior changes or safeguards are bypassed. In a security-sensitive review utility, disabling permission checks contradicts the claimed trust model and increases blast radius.

Description-Behavior Mismatch

Medium
Confidence
95% confidence
Finding
The script performs an undocumented state-changing action by appending review results to LESSONS.md, even though the skill is presented primarily as a review gate. This can leak task summaries, file names, paths, and review content into persistent storage without explicit user consent, which is risky in sensitive workspaces.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script automatically persists failure results to a lessons file with no explicit runtime notice or consent beyond comments in the source. This creates a quiet data-retention channel that may store sensitive task descriptions and review findings long after the review completes.

Static analysis

No suspicious patterns detected.