Back to skill

Security audit

reflexion

Security checks for vulnerabilities and agentic risk

Overview

This skill is coherent, but it automatically stores coding-session data and can inject or promote it into future agent instructions, with unsafe implementation details that require review before use.

Install only in a project you trust after reviewing the shell scripts. Avoid global hooks, do not commit .reflexion data, keep it out of sensitive repositories, and disable or gate automatic recall and promotion until raw entry injection, CLAUDE.md promotion, eval usage, and path interpolation are fixed.

Vulnerability Patterns
  • 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
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (6)

T02 · Agent Memory Poisoning

Error
Location
scripts/promote.sh:29
Finding

Automatic Promotion of Untrusted Content into Persistent Agent Instructions

Content
View full analysis
/dev/null)" [ -z "$RESULT" ] && continue if [ ! -f "$CLAUDE_MD" ]; then cat > "$CLAUDE_MD" << 'HEADER' # Project Guidelines HEADER fi if ! grep -qF '' "$CLAUDE_MD" 2>/dev/null; then cat >> "$CLAUDE_MD" << 'SECTION' ## Reflexion: Learned Rules Rules auto-promoted from recurring patterns. Do not edit this section manually. SECTION fi echo "$RESULT" >> "$CLAUDE_MD" ``` ### Technical Analysis The script treats the `resolution` property of every matching `.reflexion/entries/RFX-*.json` file as a trusted agent rule. Promotion only verifies that the entry has at least three occurrences, is at least one day old, has a nonempty resolution, and is not already marked as promoted. There is no validation of the content's origin, no human approval, and no filtering of instructions that attempt to override safety controls or redirect future agent actions. The resolution is appended verbatim to `CLAUDE.md`, which is a ...[truncated 1465 chars]
Remediation
View remediation

T01 · Skill Instruction Hijacking

Error
Location
scripts/recall.sh:126
Finding

Stored Instruction Injection Through Recalled Reflexion Entries

Content
View full analysis
/dev/null; then continue fi RESOLUTION="" if command -v python3 &>/dev/null; then RESOLUTION="$(python3 -c " import json, sys try: d = json.load(open('$ENTRY_FILE')) print(d.get('resolution', '')) except: pass " 2>/dev/null)" fi OCCURRENCES="$(grep -oP '"occurrences"\s*:\s*\d+' "$ENTRY_FILE" 2>/dev/null | grep -oP '\d+' || echo "1")" if [ -z "$RESOLUTION" ] && [ "${OCCURRENCES:-1}" -lt 2 ]; then continue fi TRIGGER="" if command -v python3 &>/dev/null; then TRIGGER="$(python3 -c " import json, sys try: d = json.load(open('$ENTRY_FILE')) print(d.get('trigger', '')[:200]) except: pass " 2>/dev/null)" fi RECALL_ITEMS="${RECALL_ITEMS} [$entry_id] (${TYPE}, seen ${OCCURRENCES}x): Trigger: ${TRIGGER} Resolution: ${RESOLUTION:-UNRESOLVED — this error has occurred ${OCCURRENCES}x without a known fix} Keywords: ${KEYWORDS}" done <<< "$TOP_IDS" cat << EOF ${RECALL_COUNT} relevant past learning(s) found: ${RECALL_ITEMS} Apply known resolutions if they match the current situation. If a resolution works, increment its occurrences count in the entry file. If it doesn't apply, ignore it. EOF ``` ### Technical Analysis The recall hook reads `trigger` and `resolution` fields from persistent entry files and emits them directly into the agent's context. The output labels these values as relevant past learnings and explicitly asks the agent to apply known resolutions. No output encoding, trust annotation, provenance verification, or separation between data and instructions is e ...[truncated 1379 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/status.sh:42
Finding

Arbitrary Shell Command Execution Through Evaluation of Writable Statistics

Content
View full analysis
/dev/null; then eval "$(python3 -c " import json try: s = json.load(open('$REFLEX_DIR/stats.json')) print(f'TOTAL_CAPTURED={s.get(\"total_captured\",0)}') print(f'TOTAL_RECALLED={s.get(\"total_recalled\",0)}') print(f'TOTAL_PROMOTED_STAT={s.get(\"total_promoted\",0)}') lc = s.get('last_capture') or 'never' lr = s.get('last_recall') or 'never' print(f'LAST_CAPTURE={lc}') print(f'LAST_RECALL={lr}') except: pass " 2>/dev/null)" fi ``` ### Technical Analysis Values read from `.reflexion/stats.json` are converted into shell assignment text and passed to `eval`. The generated assignments are not shell-quoted. Shell metacharacters, command substitutions, semicolons, or newlines in fields such as `last_capture` and `last_recall` are therefore interpreted as shell syntax. JSON parsing does not make the values safe for shell evaluation. The vulnerable trust transition occurs when parsed data is reconstructed as executable shell source. ### Attack Path 1. The attacker gains the ability to modify `.reflexion/stats.json`, such as through a malicious repository, committed reflexion state, or another local process. 2. The attacker sets a field to shell syntax, for example a command substitution in `last_capture`. 3. The user or agent runs `scripts/status.sh`, as recommended by the skill before major tasks. 4. Python emits the malicious value as part of an assignment. 5. `eval` parses the assignment as shell code and executes the injected command. ### Impact Assessment The payload runs with the privileges of the user or coding-agent process. It can read or alter any files available to that account, execut ...[truncated 269 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/recall.sh:126
Finding

Python Source Injection Through Interpolated Entry Paths

Content
View full analysis
/dev/null; then RESOLUTION="$(python3 -c " import json, sys try: d = json.load(open('$ENTRY_FILE')) print(d.get('resolution', '')) except: pass " 2>/dev/null)" fi TRIGGER="" if command -v python3 &>/dev/null; then TRIGGER="$(python3 -c " import json, sys try: d = json.load(open('$ENTRY_FILE')) print(d.get('trigger', '')[:200]) except: pass " 2>/dev/null)" fi done <<< "$TOP_IDS" ``` The same unsafe construction appears in promotion and status processing: ```bash RESULT="$(python3 -c " import json, sys try: with open('$entry_file') as f: e = json.load(f) ... except Exception as ex: sys.exit(0) " 2>/dev/null)" ``` ### Technical Analysis Shell-derived paths are inserted directly between single quotes in Python source supplied to `python3 -c`. Neither the entry identifier nor the resulting path is escaped for Python syntax. In `recall.sh`, entry identifiers originate from `.reflexion/index.txt` and are not checked against an identifier allowlist. An identifier containing a quote and Python syntax can terminate the intended string literal. Exploitation requires the script's file-existence check to succeed, which can be satisfied by creating a correspondingly named file or by abusing path components where filesystem access permits it. Related scripts interpolate glob-derived filenames and the externally supplied `CLAUDE_PROJECT_ROOT` path into Python source using the same unsafe pattern. Fil ...[truncated 1107 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/capture.sh:111
Finding

Incomplete Secret Redaction Before Persistent Command and Output Logging

Content
View full analysis
"$ENTRY_FILE" << ENTRY_EOF { "id": "$ENTRY_ID", "type": "error", "trigger": $TRIGGER_JSON, "context": $CONTEXT_JSON, "resolution": "", "keywords": "$(echo "$KEYWORDS" | sed 's/,/", "/g; s/^/"/; s/$/"/')", "occurrences": 1, "first_seen": "$TODAY", "last_seen": "$TODAY", "promoted": false } ENTRY_EOF ``` ### Technical Analysis The capture hook persistently stores the Bash command and up to 500 bytes of output whenever an error pattern is detected. Its redaction is based on a limited set of regular expressions. The patterns do not comprehensively cover credentials in URLs, cookies, database connection strings, private registry tokens, unlabelled random secrets, many vendor-specific token formats, quoted values with spaces, or multiline private keys. In particular, the private-key expression processes input line by line and cannot reliably redact a multiline key block. The skill only suggests adding `.reflexion/` to `.gitignore`; it does not ensur ...[truncated 945 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:53
Finding

Automatic Hook Installation from an Unpinned Mutable Repository

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Command fails | `capture.sh` auto-logs error + context to `.reflexion/entries/` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Command fails | `capture.sh` auto-logs error + context to `.reflexion/entries/` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Command fails | `capture.sh` auto-logs error + context to `.reflexion/entries/` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Command fails | `capture.sh` auto-logs error + context to `.reflexion/entries/` |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Command fails | `capture.sh` auto-logs error + context to `.reflexion/entries/` |

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The UserPromptSubmit hook uses an empty matcher, which implies ambiguous or global triggering before every user prompt. Because recall.sh injects stored prior content into prompt context, this can indiscriminately surface historical data and influence unrelated sessions, creating a direct prompt-time data leakage and context-poisoning path.

Content

No source excerpt is available for this finding.

Vague Triggers

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The empty matcher on the UserPromptSubmit hook causes the recall script to run for every user prompt without any scoping or filtering. In this skill, that broad trigger increases exposure because each prompt may be inspected, logged, or used to retrieve memory, creating unnecessary access to potentially sensitive user input and enabling unintended side effects on all sessions where the skill is installed.

Content

No source excerpt is available for this finding.

Agent Config Directory Access

High
Category
Agent Snooping
Confidence
90% confidence
Finding

The guide instructs users to modify the global agent configuration at ~/.claude/settings.json so that shell commands from this skill execute automatically across all projects. Global hook installation expands the trust boundary from one repository to every future session, meaning any flaw, unexpected behavior, or unsafe data capture in the referenced scripts affects all workspaces and may expose sensitive data from unrelated projects.

Content

Scanner excerpt · references/integration.md (reported line 42)May include surrounding context.

Global (all projects)

Add to ~/.claude/settings.json with absolute paths:

json
{

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill clearly performs file reads and writes through hooks and manual commands (capture.sh, rebuild-index.sh, writing .reflexion/entries/, and appending to CLAUDE.md), but it does not declare any explicit tool scope or permissions boundary. That mismatch increases the chance the skill will run with broader-than-expected capabilities, making persistent data modification and context poisoning harder for users to reason about or constrain.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The activation guidance is extremely broad (errors occur, user corrects the agent, before starting tasks in areas with past learnings), which can cause the skill to engage during many normal interactions. In this skill's context, broad activation matters because it increases the frequency of automatic capture, storage, and replay of user/task content, expanding both privacy exposure and the chance of stale or unsafe guidance influencing future actions.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill's core design is persistent capture, recall, and promotion of natural-language corrections and solutions across sessions. Even with secret-redaction claims, this creates a durable retention channel for user-provided content and environment details that may later be surfaced in unrelated contexts, especially because natural-language sensitivity is hard to robustly detect with simple pattern matching.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% 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.

Content

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

Claude Code (recommended)

bash
# Clone into your project or global skills
git clone https://github.com/user/reflexion.git .claude/skills/reflexion

# Or copy into an existing skills directory

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

Automatic recall injects stored entries directly into future prompt context, which means any sensitive or misleading content captured earlier can be replayed without fresh review. In this skill, that danger is amplified because recall happens pre-prompt and is designed to influence agent behavior, so the feature creates both data leakage risk and a memory-poisoning mechanism if bad entries are stored.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill describes automatic prompt-time recall and context injection but does not prominently warn users that previously captured data may be inserted into future prompts. That omission undermines informed consent and can cause users to expose corrections, task details, or environment-specific information without realizing it will persist and reappear later.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The instructions explicitly direct the agent to log user corrections into persistent JSON entries, including trigger, context, and resolution text. User corrections often contain sensitive workflow details, internal project conventions, or proprietary information, so persisting them creates a straightforward path for later disclosure via search, recall, or promotion.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The integration guide tells users to install automatic PostToolUse and UserPromptSubmit hooks that invoke shell scripts on every Bash tool use and prompt submission, but it does not disclose that these hooks may capture prompts, commands, tool outputs, and other potentially sensitive data and persist them to disk. In a coding-agent environment, that data can include secrets, proprietary code context, internal filenames, error traces, or user inputs, so silent persistence materially increases privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script persistently writes captured Bash tool output and the originating command into .reflexion/entries without any explicit user notice or consent at capture time. Even with partial redaction, command output often contains sensitive data such as file contents, stack traces, internal paths, tokens that do not match the regexes, or proprietary code fragments, so this creates a privacy and data-retention risk on disk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script ingests the user's prompt from stdin, derives keywords from it, and emits matched historical entries into system context without any sanitization boundary or disclosure. In this skill's context, that is more dangerous because recalled entries become privileged context for the agent, enabling prompt-to-system dataflow and possible prompt injection or unintended disclosure of prior sensitive project learnings triggered by attacker-chosen prompt terms.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The recall hook is documented as a read-only context injector, but it also invokes promote.sh asynchronously, which can mutate project memory as a side effect of merely submitting a prompt. This violates least surprise and least privilege: a user interaction that should only retrieve data can trigger persistent state changes, creating a covert write path that could be abused if promotion logic is flawed or poisoned by prior entries.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The inline comment asserts a stronger condition than the code enforces: it implies promoted entries are already present in CLAUDE.md, yet the implementation merely skips entries whose JSON contains a promoted=true marker. If that flag is stale or incorrect, the behavior diverges from the documented intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This code updates a local stats file and invokes promote.sh asynchronously, both of which are state-changing operations. The script includes internal comments, but no user-facing print/log/confirmation that local files are modified and a secondary script may run in the background.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.