Back to skill

Security audit

self-reflection-loop

Security checks for vulnerabilities and agentic risk

Overview

This skill has a real self-reflection purpose, but its automatic refinement path can run arbitrary shell commands and it stores reusable preferences without strong controls.

Review this skill carefully before installing. Use only in a sandboxed workspace, avoid --refine-cmd unless you fully trust the artifact, rubric, and command template, and do not store sensitive information in preferences or notes. The package does not show exfiltration or obvious malicious intent, but its command execution and persistent learning features need clearer user control.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • 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

Error
Location
scripts/reflector.py:169
Finding

Arbitrary Shell Command Injection in the Refinement Loop

Content
View full analysis

Vulnerability Details

File Location: scripts/reflector.py, lines 169–172
Vulnerability Type: OS command injection through unsafe shell interpolation
Risk Level: High

Vulnerable Code

python
gap_txt = "; ".join(g["rectify"] for g in res["gaps"])
cmd = a.refine_cmd.replace("{artifact}", cur).replace("{gaps}", gap_txt)
r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
nxt = (r.stdout or "").strip().splitlines()

Technical Analysis

The refinement loop constructs a shell command by replacing placeholders in the caller-provided --refine-cmd string. It then executes the resulting command with shell=True.

The interpolated values are not escaped or validated:

  • cur contains an artifact path that may be controlled by the caller.
  • gap_txt contains remediation text derived from rubric criteria loaded from a caller-selected JSON file.
  • The refinement command itself is supplied directly through a command-line argument.

Shell metacharacters in an artifact path or rubric-derived field are therefore interpreted by the operating system shell. Surrounding a placeholder with quotes in the documented command is insufficient because an attacker can include matching quotes followed by shell operators.

Attack Path

  1. An attacker supplies a malicious rubric whose failed criterion contains shell metacharacters in its description, or provides a maliciously crafted artifact filename.
  2. The criterion fails during assessment.
  3. The attacker-controlled content is copied into the generated rectify value and then into gap_txt.
  4. The loop replaces {gaps} or {artifact} in the refinement command with that content.
  5. subprocess.run(..., shell=True) passes the complete string to the shell.
  6. The shell interprets the injected operators and executes attacker-selected commands with the privileges of the user running the Skill.

Impact Assessment

Successful explo ...[truncated 410 chars]

Remediation
View remediation

Remediation Suggestions

  • Remove shell=True and execute refinement programs with shell=False.
  • Represent commands as explicit argument arrays rather than shell command strings.
  • Pass artifact paths and gap data as separate arguments, through standard input, or through a securely created JSON file.
  • Do not perform textual placeholder replacement inside an executable command.
  • Validate refinement executables against an allowlist where the environment permits only approved tools.
  • Reject unexpected control characters and enforce strict schemas for rubric fields.
  • If shell execution is an essential advanced feature, make it an explicit high-risk opt-in and ensure no untrusted values are interpolated into the command.
  • Run refinement processes in a restricted sandbox with minimal filesystem, credential, and network access.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reflector.py:85
Finding

Predictable Temporary File Enables File Clobbering and Symlink Attacks

Content
View full analysis

Vulnerability Details

File Location: scripts/reflector.py, lines 85–96
Vulnerability Type: Insecure temporary-file creation
Risk Level: Medium

Vulnerable Code

python
if t == "code_compile":
    if not text.strip().endswith(".py"):
        # Write source text to a temporary file before compiling it.
        tmp = "_reflect_tmp.py"
        open(tmp, "w", encoding="utf-8").write(text)
        fp = tmp
    else:
        fp = text
    r = subprocess.run([sys.executable, "-m", "py_compile", fp],
                       capture_output=True, text=True)
    if os.path.exists("_reflect_tmp.py"):
        os.remove("_reflect_tmp.py")
    return r.returncode == 0, (r.stderr.strip()[:300] or "Compilation succeeded")

Technical Analysis

The code uses the fixed relative filename _reflect_tmp.py in the current working directory. The file is opened in write mode without exclusive creation, ownership verification, symlink protection, or a securely generated name.

If that path already exists, it is silently truncated. If it is a symbolic link, the write follows the link and overwrites the linked target. Concurrent invocations can also overwrite or delete each other's temporary files, leading to corrupted assessments and race conditions.

The translated comments and status text above preserve the behavior of the audited source; the vulnerable operations are the fixed filename, ordinary open() call, and path-based cleanup.

Attack Path

  1. An attacker who can prepare the working directory creates _reflect_tmp.py as a symbolic link to another file writable by the Skill process.
  2. The attacker causes check_criterion to evaluate source text rather than an existing Python path.
  3. open("_reflect_tmp.py", "w") follows the symbolic link and truncates or overwrites its target with the supplied source text.
  4. The script invokes the compiler against the selected path.
  5. Cleanup remove ...[truncated 663 chars]
Remediation
View remediation

Remediation Suggestions

  • Use tempfile.TemporaryDirectory or tempfile.NamedTemporaryFile with a unique, securely created path.
  • Place temporary files in an operating-system-managed private temporary directory rather than the caller-controlled working directory.
  • Use a try/finally block or context manager to guarantee cleanup.
  • Do not reopen a temporary path by name where a file descriptor can be used safely.
  • Ensure temporary content is accessible only to the current user.
  • Avoid deleting a path unless the process can verify that it is the same regular file it created.
  • Add concurrency tests and symlink-based regression tests.

T02 · Agent Memory Poisoning

Warning
Location
scripts/learner.py:98
Finding

Unvalidated Persistent Preferences Can Poison Future Agent Behavior

Content
View full analysis

Vulnerability Details

File Location: scripts/learner.py, lines 98–102; behavioral reuse is directed by SKILL.md, lines 56–69
Vulnerability Type: Persistent agent-memory poisoning
Risk Level: Medium

Vulnerable Code

python
def record_preference(skill_dir, key, value):
    data = load_learning(skill_dir)
    data["preferences"][key] = value
    save_learning(skill_dir, data)
    return data

The Skill documentation directs important user preferences to be written to learned_patterns.json and automatically adopted during later uses. It also recommends feeding accumulated lessons back into future behavior.

Technical Analysis

record_preference accepts arbitrary key and value strings and stores them in persistent JSON state. There is no schema validation, instruction-content filtering, provenance record, user or session isolation, expiration policy, approval workflow, or distinction between passive data and executable behavioral guidance.

The persistence operation is especially significant because the Skill documentation directs the Agent to use stored preferences in subsequent invocations. An attacker-controlled value can therefore be treated as a durable instruction rather than as untrusted data.

The implementation also stores arbitrary error names and notes in related learning records. Those fields can retain sensitive text or instruction-like content, although the direct behavioral reuse instruction is clearest for the preferences object.

Attack Path

  1. An attacker or untrusted task invokes the prefer command with instruction-like content as the preference value.
  2. record_preference writes the content into learned_patterns.json.
  3. The data remains present after the originating task has completed.
  4. During a later task, an Agent loads the Skill and follows its documented instruction to adopt stored preferences.
  5. The persisted attacker-controlled rule influences ...[truncated 938 chars]
Remediation
View remediation

Remediation Suggestions

  • Define a strict allowlist of supported preference keys and constrained value types.
  • Reject instruction-like free-form values where a boolean, enumeration, or bounded scalar is sufficient.
  • Treat stored values as untrusted data and never concatenate them into Agent instructions without delimiting and validation.
  • Require explicit, informed user approval before persisting a preference and before applying it in a later session.
  • Record provenance, owner, scope, creation time, expiration time, and the task that created each entry.
  • Isolate memory by user, workspace, and Skill instance to prevent cross-context influence.
  • Provide commands to inspect, revoke, and delete learned data.
  • Prevent secrets and sensitive task content from being stored; apply appropriate file permissions.
  • Never automatically rewrite SKILL.md or other trusted instruction files from learned notes.
  • Keep trusted policy separate from mutable learning data and ensure trusted instructions explicitly state that memory cannot override system, developer, or safety requirements.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The documented behavior materially exceeds and diverges from the declared purpose: instead of only running a reflection loop, it also introduces persistent logging, preference storage, and skill evolution behavior. This mismatch is dangerous because operators may approve or invoke the skill under false assumptions, enabling data collection or file modification that was not transparently disclosed.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The manifest describes a Reflexion-style closed loop that evaluates outputs, performs anchored checks such as compilation/word-count/keyword/regex validation, and feeds lessons into subsequent regeneration until quality thresholds are met. This code instead records usage telemetry, stores user preferences, aggregates simple statistics, and prints suggestions from a JSON file; it contains no generation loop, scoring, validation gates, or iterative refinement behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The self-reflection engine's justified role is assessment and iteration, but loop mode additionally provides a generic shell execution primitive through --refine-cmd. That broad execution capability materially expands the attack surface and can be repurposed to run arbitrary system commands unrelated to reflection or validation.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
99% confidence
Finding

This is a classic tool-parameter-abuse issue: the skill exposes a powerful execution sink and fills it with attacker-influenced parameters. In the context of an iterative agent loop, the danger is amplified because the command can be triggered repeatedly and can consume artifact-derived content, enabling reliable arbitrary code execution or destructive system actions.

Content

Scanner excerpt · scripts/reflector.py (reported line 174)May include surrounding context.

python
# 自动整改:把本轮缺口作为上下文交给 refine 命令,产出下一版产物
                gap_txt = "; ".join(g["rectify"] for g in res["gaps"])
                cmd = a.refine_cmd.replace("{artifact}", cur).replace("{gaps}", gap_txt)
                r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
                nxt = (r.stdout or "").strip().splitlines()
                nxt = nxt[-1] if nxt else ""
                if nxt and os.path.exists(nxt):

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
96% confidence
Finding

The skill explicitly documents shell execution and file-writing workflows but does not declare any tool scope or permission boundary. That creates an authorization and review gap: downstream systems or users cannot easily understand or constrain what the skill may execute, increasing the risk of unexpected command execution or filesystem modification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The entire skill description and command guidance are presented only in Chinese, with no indication that users may choose another language. For a general-purpose public skill, this can amount to a language-policy issue unless the locale restriction is explicit and justified or the user is given a choice.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger condition is extremely broad, covering generic requests for self-correction, refinement, and quality gating. Overbroad activation increases the chance the skill runs in unrelated contexts, which can unnecessarily invoke shell/file capabilities or persistence logic on tasks where users did not intend that behavior.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill introduces persistent collection of usage history, error patterns, and user preferences beyond its stated self-reflection purpose. Unnecessary retention broadens the privacy and security footprint, and the stored data could later be mined, leaked, or reused in ways the user did not expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill description does not warn users that learned patterns and user preferences are stored persistently. Hidden persistence undermines informed consent and can lead to privacy harm, especially when users believe they are only requesting one-off refinement rather than long-term profiling.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill instructs itself to modify its own SKILL.md over time, which is a self-modifying behavior outside the advertised evaluation role. Self-modification is risky because it can silently expand triggers, permissions, or instructions across runs, undermining review integrity and making future behavior less predictable.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill explicitly directs persistent storage of user preferences for reuse in future interactions. Persistent preference storage creates a durable profile that may contain sensitive behavioral data, and reusing it automatically in later sessions can exceed user expectations or organizational data-governance requirements.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The module persistently stores arbitrary per-skill user preferences, notes, and operational history across skills under the user's home directory. In an agent ecosystem, this broad retention can capture sensitive prompts, error notes, or preferences without minimization, creating privacy leakage and unintended cross-session profiling if other components can read the files.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The natural-language documentation, CLI descriptions, and output strings are presented only in Chinese, which imposes a specific language on users without any visible opt-in or alternative. Under the stated policy, forcing a language or locale without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code records user preferences and free-form notes to persistent storage without any user-facing notice at the time of collection. If notes contain sensitive data, credentials, or internal prompts, this silent retention increases privacy and data-handling risk because users and calling agents may not realize the information is being written to disk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring, CLI description, usage notes, and runtime output are written exclusively in Chinese, which imposes a specific language choice on users. There is no indication of language selection, opt-in, or justification for the locale restriction.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/reflector.py (reported line 76)May include surrounding context.

python
fp = tmp
        else:
            fp = text
        r = subprocess.run([sys.executable, "-m", "py_compile", fp],
                           capture_output=True, text=True)
        if os.path.exists("_reflect_tmp.py"):
            os.remove("_reflect_tmp.py")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
99% confidence
Finding

The loop mode constructs a shell command from user-controlled inputs and executes it with shell=True. Because both the artifact path and generated gap text are interpolated into the command string without escaping, an attacker can inject shell metacharacters and achieve arbitrary command execution on the host.

Content

Scanner excerpt · scripts/reflector.py (reported line 174)May include surrounding context.

python
# 自动整改:把本轮缺口作为上下文交给 refine 命令,产出下一版产物
                gap_txt = "; ".join(g["rectify"] for g in res["gaps"])
                cmd = a.refine_cmd.replace("{artifact}", cur).replace("{gaps}", gap_txt)
                r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
                nxt = (r.stdout or "").strip().splitlines()
                nxt = nxt[-1] if nxt else ""
                if nxt and os.path.exists(nxt):

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The code executes a shell-based refinement command automatically, with no interactive warning, confirmation, or prominent safety notice. In an agent skill context, this increases the likelihood of unsafe execution because users may enable loop mode without appreciating that it grants arbitrary command execution to the skill pipeline.

Content

No source excerpt is available for this finding.

Tainted flow: 'cmd' from open (line 173, file read) → subprocess.run (code execution)

Medium
Category
Data Flow
Confidence
99% confidence
Finding

There is a tainted data flow into subprocess.run: untrusted content from the artifact/rubric-derived text is inserted into cmd and then executed by the shell. This creates a direct path from attacker-controlled file content or paths to code execution, which is especially dangerous in an automation skill likely to process untrusted artifacts.

Content

Scanner excerpt · scripts/reflector.py (reported line 174)May include surrounding context.

python
# 自动整改:把本轮缺口作为上下文交给 refine 命令,产出下一版产物
                gap_txt = "; ".join(g["rectify"] for g in res["gaps"])
                cmd = a.refine_cmd.replace("{artifact}", cur).replace("{gaps}", gap_txt)
                r = subprocess.run(cmd, shell=True, capture_output=True, text=True)
                nxt = (r.stdout or "").strip().splitlines()
                nxt = nxt[-1] if nxt else ""
                if nxt and os.path.exists(nxt):

Static analysis

No suspicious patterns detected.