Back to skill

Security audit

weclone-twin-reply

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent review-gated reply-drafting helper, but users should keep its persona folder tightly curated because it can include extra Markdown files in the generated prompt.

Before installing, treat the persona directory as sensitive: keep only intended persona Markdown files there, review generated prompts before sending them to another model, and do not approve outbound replies unless you have checked the draft and risk flags.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (2)

T01 · Skill Instruction Hijacking

Error
Location
scripts/render_clone_prompt.py:108
Finding
Untrusted Runtime Content Can Hijack the Downstream Model<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render_clone_prompt.py:108-125`; `assets/clone_prompt_template.md:48-64` **Vulnerability Type**: T01: Skill Instruction Hijacking **Risk Level**: High ### Vulnerable Code ```python persona_text = "\n\n".join( format_section(f"Persona File: {name}", body) for name, body in persona_sections ).strip() extra_text = "\n\n".join( format_section(f"Extra Context: {name}", body) for name, body in extra_sections ).strip() prompt = render_template( template_text, { "PERSONA_SECTIONS": persona_text, "SCENE_TEXT": scene_text, "DIALOGUE_TEXT": dialogue_text, "EXTRA_SECTIONS": extra_text, }, ) return re.sub(r"\n{3,}", "\n\n", prompt).strip() + "\n" ``` The values are interpolated directly into the following instruction-bearing template: ```markdown {{PERSONA_SECTIONS}} ## Runtime Scene {{SCENE_TEXT}} ## Active Dialogue {{DIALOGUE_TEXT}} {{EXTRA_SECTIONS}} ## Decision Rule If a faithful imitation would violate the guardrails, produce the safest useful draft that still fits the person's stable values and voice, and flag the risk instead of complying. ``` ### Technical Analysis Persona files, scene descriptions, active dialogue, and optional context are inserted verbatim into a prompt that is sent to a downstream model. The renderer does not structurally distinguish trusted instructions from untrusted content, escape instruction-like text, or add an explicit rule requiring the model to treat imported material exclusively as quoted data. The active dialogue may contain content controlled by another conversation participant. Such a participant can place prompt-injection instructions into a message, including directions to ignore the required output format, disclose persona information, or generate content unrelated to the requested reply. Compromised or untrusted persona and extra-context files provide equivalent injection channels. Although th ...[truncated 1762 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat persona data, scene text, dialogue, and extra context as untrusted data rather than instructions. 2. Add explicit authoritative instructions stating that commands, policies, role changes, output requests, and tool-use directions appearing inside imported sections must never be followed. 3. Delimit each imported value using a robust structured representation, such as JSON fields or clearly identified quoted-data blocks. 4. Where supported, place immutable guardrails in a system or developer message and pass imported content through a lower-trust user or data channel. 5. Move or repeat the authoritative security and output requirements after all imported content so that the final instructions unambiguously reject instructions found in the data sections. 6. Validate the downstream response against the required `DRAFT_REPLY`, `RISK_FLAGS`, and `REVIEW_NOTE` structure. Reject and regenerate malformed output. 7. Detect common prompt-injection indicators in runtime files and raise a review warning rather than silently rendering them. 8. Minimize the supplied context and redact sensitive fields that are not necessary for drafting. 9. Preserve the existing explicit human-approval gate and clearly display injection warnings to the reviewer before any send operation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_clone_prompt.py:86
Finding
Unrestricted Automatic Loading of Additional Persona Markdown Files<![CDATA[ ## Vulnerability Details **File Location**: `scripts/render_clone_prompt.py:86-96` **Vulnerability Type**: T09: Insecure Skill Coding Practices **Risk Level**: Medium ### Vulnerable Code ```python known_names = set(REQUIRED_PERSONA_FILES) | set(OPTIONAL_PERSONA_FILES) extras = sorted( path for path in persona_dir.glob("*.md") if path.name not in known_names and path.name not in excluded_names ) for path in extras: sections.append((path.name, path.read_text(encoding="utf-8").strip())) return sections ``` ### Technical Analysis The renderer automatically reads every additional `*.md` file located directly in the persona directory. The files are included without an explicit allowlist, relevance decision, user confirmation, content-size limit, or sensitivity check. This behavior conflicts with the documented execution rule in `SKILL.md`, which states that additional Markdown files should be loaded only when they materially improve the reply. In practice, the implementation cannot determine relevance and indiscriminately adds all matching files to the rendered prompt. A sensitive Markdown file accidentally stored in the persona directory will therefore be exposed through standard output, an output file, or the downstream model context. An attacker with the ability to place a Markdown file in that directory can also expand the prompt-injection surface by adding malicious instructions. ### Attack Path 1. A sensitive, irrelevant, or attacker-controlled Markdown file is placed in the configured persona directory. 2. The file does not use one of the recognized persona filenames and does not share the basename of a scene, dialogue, or extra-context file. 3. `persona_dir.glob("*.md")` discovers the file automatically. 4. The renderer reads its complete contents and adds them to `persona_sections`. 5. The contents are embedded in the generated prompt. 6. The data is exposed through stdout, the configured output file, or the downstream mode ...[truncated 853 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove automatic discovery of arbitrary `*.md` files. 2. Default to loading only the documented files: `profile.md`, `persona_examples.md`, `guardrails.md`, and optional `state.md`. 3. Introduce an explicit repeatable option such as `--persona-extra <file>` for each additional persona file. 4. Require confirmation before importing extra files and display the resolved file paths to the user. 5. Resolve paths safely and verify that explicitly selected persona extras remain inside the intended persona directory unless external files are deliberately supported. 6. Apply per-file and aggregate size limits to prevent excessive context ingestion. 7. Reject symbolic links or verify their resolved targets when persona-directory containment is required. 8. Scan imported extras for secrets and prompt-injection indicators, and generate review warnings when suspicious content is detected. 9. Record the exact list of included files in the rendered output or an audit log so reviewers can verify the context supplied to the model. ]]>
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
84% confidence
Finding
The skill instructs the agent to read persona files and create runtime files like scene.md and dialogue.md, which implies file read/write capability, but it does not declare an explicit tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege controls and can cause an agent runtime to grant broader filesystem access than reviewers expect, increasing the chance of unintended data exposure or file modification.

Static analysis

No suspicious patterns detected.