Back to skill

Security audit

Prompt Version Control

Security checks for vulnerabilities and agentic risk

Overview

The skill is mostly aligned with prompt versioning, but its CLI has unsafe input handling that can write outside its prompt folder and may run local code with crafted prompt names.

Review before installing. Use this only with trusted prompt names and in repositories where local file mutation is acceptable. Do not run it with secrets exposed in the environment until prompt-name validation is enforced and Python helpers pass paths as argv instead of interpolating them into source. Treat any future remote sync as uploading prompt contents to the configured git remote.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/prompt-vc.sh:144
Finding

Path Traversal Through Unvalidated Prompt Names

Content
View full analysis
/dev/null || true [ -z "$name" ] && die "Usage: prompt-vc.sh add [--template type] [--description ...]" while [ $# -gt 0 ]; do case "$1" in --template) template="$2"; shift 2 ;; --description) description="$2"; shift 2 ;; *) shift ;; esac done local prompt_file="$PROMPT_DIR/prompts/${name}.yaml" [ -f "$prompt_file" ] && die "Prompt '${name}' already exists at ${prompt_file}" local system_text user_text case "$template" in chat) system_text="You are a helpful AI assistant. Respond concisely and accurately." user_text="{{query}}" ;; classifier) system_text="You are a text classifier. Analyze the input and classify it into the appropriate category." user_text="Classify the following: {{input}}" ;; generator) system_text="You are a content generator. Create high-quality output based on the given prompt." user_text="Generate: {{prompt}}" ;; extractor) system_text="You are an information extractor. Extract structured data from unstructured text." user_text="Extract from: {{text}}" ;; custom) system_text="" user_text="{{input}}" ;; *) die "Unknown template: $template (use: chat|classifier|generator|extractor|custom)" ;; esac cat > "$prompt_file" <
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/prompt-vc.sh:422
Finding

Arbitrary Python Code Execution Through Source-Code Interpolation

Content
View full analysis
/dev/null || echo "0")" ``` The report command repeats the same pattern with the metrics path: ```bash python3 -c " import json with open('${metrics_file}') as f: data = json.load(f) trend = data.get('quality_trend', []) if trend: print(f\"Total versions: {len(trend)}\") print(f\"Best: {max(trend):.1f}\") print(f\"Worst: {min(trend):.1f}\") print(f\"Latest: {trend[-1]:.1f}\") print() print('Sparkline: ' + ''.join('█' * max(1, int(x)) + '▌' if x % 1 >= 0.5 else '█' * int(x) for x in trend)) " 2>/dev/null || echo "(No trend data available)" ``` ### Technical Analysis Both `prompt_file` and `metrics_file` contain the prompt name supplied through the CLI. The script places these values inside a single-quoted Python string literal contained in a larger `python3 -c` program. Because prompt names are not validated or escaped, a name containing a single quote and valid Python syntax can terminate the intended string literal and introduce additional expressions or statements. Python then parses and executes the resulting attacker-modified source code. Quoting the outer shell variable does not solve this issue. Shell quoting only ensures that the generated source is passed as one argument to `python3`; it does not prevent Python metacharacters in the expanded value from changing the program parsed by the Python interpreter. The use of `yaml.safe_load` prevents unsafe YAML object construction but has no bearing on this vulnerability. Execution occurs wh ...[truncated 2086 chars]
Remediation
View remediation
/dev/null || echo "0" )" ``` 3. Apply the same pattern to report generation: ```bash python3 -c ' import json import sys with open(sys.argv[1], encoding="utf-8") as f: data = json.load(f) trend = data.get("quality_trend", []) # Generate the report without interpolating the path into this source. ' "$metrics_file" ``` 4. Enforce `^[a-z][a-z0-9-]*$` for every prompt name before constructing any path. 5. Prefer a checked standalone Python helper script over large dynamically assembled `python3 -c` programs. 6. Do not suppress all Python diagnostics during security-sensitive parsing. Return a controlled error while retaining actionable logs. 7. Add regression tests using names containing single quotes, double quotes, semicolons, parentheses, newlines, backslashes, and Python expressions. 8. Run the CLI under least privilege and avoid exposing unnecessary secrets in its environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| `SKILL.md` | Full design document (this file) |

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
95% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · scripts/prompt-vc.sh (reported line 259)May include surrounding context.

sh
cp "$prompt_file" "${history_dir}/${new_version}.yaml"

  # Clean up pre-edit
  rm -f "${history_dir}/_pre_edit.yaml"

  echo "Updated '${name}': ${current_version} → ${new_version} (${bump} bump)"
}

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Line L303 states that all test output is simulated offline and does not require API keys, which conveys a constrained, local-only testing model. However, the same document elsewhere specifies remote sync via git/GitHub/GitLab (L020, L135-L138) and use of $EDITOR plus git/diff/python as runtime components (L276-L301), so the documentation presents a materially inconsistent picture of what the implementation may invoke and depend on.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The help text describes prompt-vc.sh test <name> as running an A/B test, which implies evaluating prompt versions with real test cases or model outputs. In code, the command explicitly falls back to synthetic cases and computes fake metrics from prompt lengths, with comments at L481-L482 confirming it is only a simulation for CLI testing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The rollback command copies a historical version over the current prompt file and then writes a new history entry, which is a user-data-modifying operation. Although the script prints status after the change, there is no confirmation prompt or pre-action warning before the overwrite occurs.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest advertises a remote sync capability to GitHub/GitLab but provides no warning, consent prompt, or explanation that prompt contents and related metadata may be transmitted off-host. Because prompts can contain proprietary instructions, secrets, or sensitive business context, an unsuspecting user could exfiltrate data simply by invoking the sync workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The heading Prompt Version Control (Prompt 版本控制器) introduces a specific additional language in user-facing documentation, but the skill does not explain whether bilingual output is intended, optional, or required. Under the language/locale policy rule, forcing or implying a language presentation without user opt-in can be a policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

When a Git repository is detected, init silently modifies the user's .gitignore file by appending an entry. This is a file write affecting repository configuration, and the code does not disclose this behavior until after initialization completes.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.