T09 · Insecure Skill Coding Practices
- Location
scripts/compress.js:37- Finding
Indirect prompt injection through untrusted text concatenation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/compress.js, lines 37-49
Vulnerability Type: Indirect prompt injection caused by insecure prompt construction
Risk Level: Mediumjavascript function semanticCompress(text, options = {}) { const defaultOptions = { targetCompression: 0.5, preserveAccuracy: true, model: null }; const config = { ...defaultOptions, ...options }; const fullPrompt = COMPRESSION_PROMPT + '\n' + text; return { prompt: fullPrompt, originalLength: text.length, originalTokens: Math.ceil(text.length / 4), config: config }; }Technical Analysis
The
textargument is appended directly to the LLM instructions without a structured trust boundary, escaping mechanism, or explicit rule that directives contained in the source text must be treated only as data. The README documents that consumers can submit the resultingresult.promptto an LLM.If
textcontains attacker-controlled instructions, the receiving model may interpret those instructions as part of the active prompt rather than as content to compress. An attacker could consequently redirect the model away from compression, manipulate its output, or request disclosure of information present elsewhere in the model context.This is an insecure prompt-construction pattern rather than evidence of intentional instruction hijacking by the Skill itself.
Attack Path
- An attacker places adversarial instructions in a document, conversation history, or other text processed by the Skill.
- A caller passes that content to
semanticCompress. - Line 43 concatenates the untrusted content directly after the compression instructions.
- Following the documented workflow, the caller submits
result.promptto an LLM. - The model may follow the embedded attacker instructions instead of treating them solely as source material.
- The generated output may contain a ...[truncated 718 chars]
- Remediation
View remediation
Remediation Suggestions
- Send trusted compression instructions and untrusted source content as separate structured messages or API fields rather than combining them into one prompt string.
- State explicitly in the trusted instruction layer that the source text is untrusted data and that any instructions, role declarations, tool requests, or formatting commands inside it must not be followed.
- Enclose the source text in an unambiguous data structure, such as a JSON field, while clarifying that delimiters do not independently provide a security boundary.
- Apply input-size limits and reject unsupported input types before constructing the request.
- Validate the model response against the expected compression task. Reject outputs that contain tool calls, unexpected role changes, requests for secrets, or content unrelated to the supplied source.
- When sensitive context is involved, submit only the minimum data required for compression and avoid placing credentials, system instructions, or unrelated private material in the same model context.
- Add adversarial tests containing embedded instructions, fake role markers, delimiter-breaking attempts, and requests to reveal context.
