T09 · Insecure Skill Coding Practices
- Location
bin/nuclear_brief.py:91- Finding
Untrusted News Content Is Passed Directly to the Generation Model
- Content
View full analysis
Vulnerability Details
File Location:
bin/nuclear_brief.py:91-107,bin/nuclear_brief.py:116-136,bin/nuclear_brief.py:185-195, andSKILL.md:28
Vulnerability Type: Indirect prompt injection through untrusted retrieved content
Risk Level: MediumVulnerable Code
python def build_knowledge(items: List[Dict[str, Any]], limit: int) -> List[str]: knowledge: List[str] = [] count = 0 for raw in items: if count >= limit: break article = normalize_article(raw) if not article["title"] or not article["link"]: continue parts = [ f"Title: {article['title']}", f"Source: {article['source'] or 'Unknown'}", f"Date: {article['date'] or 'Unknown'}", f"Link: {article['link']}", ] if article["snippet"]: parts.append(f"Snippet: {article['snippet']}") knowledge.append("\n".join(parts)) count += 1 return knowledgepython def generate_brief( token: str, model: str, topic: str, audience: str, knowledge: List[str], max_tokens: int, timeout: int, ) -> str: system_prompt = ( "You are a policy analyst assistant. Use ONLY the provided knowledge. " "If evidence is missing, say so. Do not invent facts." ) user_prompt = ( f"Create a concise nuclear energy policy brief for {audience}.\n" f"Topic focus: {topic}.\n\n" "Format:\n" "1. Top changes (3-5 bullets)\n" "2. Why it matters (3 bullets)\n" "3. Risks and uncertainties (2-3 bullets)\n" "4. Recommended actions (3 bullets)\n" "5. Sources (list of titles + links)\n" ) payload = { "model": model, "messages": [{"role": "user", "content": user_prompt}], "knowledge": knowledge, "system_pro ...[truncated 2784 chars]- Remediation
View remediation
Remediation Suggestions
- Explicitly identify every retrieved article field as untrusted data in the system prompt.
- Add a high-priority instruction that commands found in titles, snippets, sources, dates, and URLs must never be followed.
- Wrap each article and field in clear structured delimiters, preferably a documented JSON schema rather than concatenated free-form text.
- Validate links before model submission and output:
- Permit only
httpsURLs. - Reject credentials, control characters, malformed hosts, and unexpected schemes.
- Consider an allowlist of trusted publishers where appropriate.
- Permit only
- Limit the length of every external field and reject control characters or abnormal content.
- Validate the generated response before printing it:
- Enforce the required five-section structure.
- Confirm that every cited URL appeared in the retrieved dataset.
- Reject newly invented or modified links.
- Ensure cited titles correspond to retrieved records.
- Do not require unconditional verbatim forwarding. Permit the calling agent or a deterministic validator to reject malformed, unsafe, or instruction-bearing output.
- Consider a two-stage design in which retrieved data is first converted into a strict factual schema and only validated fields are used for generation.
