T01 · Skill Instruction Hijacking
- Location
scripts/generate-skill.sh:73- Finding
Generated Skill fields permit persistent instruction and YAML injection
- Content
View full analysis
Vulnerability Details
File Location:
scripts/generate-skill.sh:73-74, 98, 148-153
Vulnerability Type: Persistent instruction injection through insufficient input validation
Risk Level: MediumVulnerable Code
bash # Check high-risk fields for prompt injection check_prompt_injection "description" "$DESCRIPTION" check_prompt_injection "instructions" "$INSTRUCTIONS"bash # Sanitize skill name: lowercase, hyphens only SLUG=$(printf '%s' "$NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g' | sed 's/--*/-/g' | sed 's/^-//;s/-$//')bash # Write SKILL.md using printf to avoid echo expansion issues { printf '%s\n' "---" printf 'name: %s\n' "$SLUG" printf 'description: %s\n' "$DESCRIPTION" if [ -n "$METADATA" ]; then printf '%s\n' "$METADATA" fi printf '%s\n' "---" printf '\n' printf '# %s\n' "$NAME" printf '\n' printf '%s\n' "$INSTRUCTIONS" } > "$SKILL_DIR/SKILL.md"Technical Analysis
The generator applies a finite prompt-injection phrase denylist only to
DESCRIPTIONandINSTRUCTIONS. The originalNAMEvalue is not passed tocheck_prompt_injection(), even though it is written into the generated document body.The validation also allows carriage returns and newlines in the name, description, and instructions. In particular,
DESCRIPTIONis inserted directly into YAML frontmatter without YAML quoting, escaping, or scalar serialization. A multiline description can therefore introduce arbitrary YAML fields or a---delimiter that prematurely terminates the frontmatter. Subsequent lines then become prompt-loaded Markdown instructions.The phrase denylist does not provide structural protection and can be bypassed using instructions that avoid the enumerated wording. The generated file may consequently contain persistent behavioral instructions even though the project presents the filtering as a security boundary.
...[truncated 1328 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject carriage returns, line feeds, NUL bytes, and YAML document delimiters in all frontmatter scalar inputs.
- Validate
NAMEseparately and use only the validated slug in both frontmatter and headings. - Pass every prompt-loaded input field, including
NAME, through the same content-security policy. - Serialize frontmatter with a trusted YAML implementation rather than constructing it with
printf. - Prefer an allowlist of permitted single-line characters for names and descriptions.
- Treat phrase matching only as defense in depth, not as the primary injection boundary.
- Parse the completed file and confirm that it contains exactly one frontmatter block with the expected fields.
- Require explicit operator approval of the exact generated file before installation or activation.
- Extend
validate.shto reject duplicate delimiters, unexpected frontmatter fields, multiline scalar injection, and malformed YAML.
