T01 · Skill Instruction Hijacking
- Location
scripts/unified_query.py:190- Finding
Indirect Prompt Injection Through Untrusted Archive Content
- Content
View full analysis
Vulnerability Details
File Location:
scripts/unified_query.py, lines 190-236
Vulnerability Type: Indirect prompt injection
Risk Level: MediumVulnerable Code
python def build_summary_prompt(query: str, days: float, items: list[dict[str, Any]]) -> str: snippets: list[str] = [] for index, item in enumerate(items[:20], start=1): snippets.extend( [ f"[{index:02d}] 来源: {item['source_label']} / {item['container']}", f"标题: {item['title']}", f"时间: {item['timestamp'] or item['time_label']}", f"命中方式: {', '.join(item.get('retrieval_modes') or [])}", (item.get("content") or "")[:600], "", ] ) evidence = "\n".join(snippets).strip() return f"""你是一位本地投研资料库检索助手。请根据最近 {days:g} 天关于“{query}”的命中文本,生成一份适合手机阅读的中文摘要。 必须遵守以下要求: 1. 第一段必须叫“检索结论”,直接回答最近 {days:g} 天关于“{query}”有哪些确定更新。 2. 第二部分必须叫“时间线 / 重点更新”,优先按时间顺序列出高价值变化。 3. 第三部分必须叫“行业 / 标的归类”,按行业或具体标的分组。 4. 第四部分必须叫“边际变化”,重点突出加单、涨价、公告、订单、政策、业绩、预期差。 5. 第五部分必须叫“来源分布”,指出这些信息主要来自哪些库或归档源。 6. 最后一部分必须叫“待验证”,单独放传闻、重复或证据弱的内容。 7. 总字数控制在 900-1200 字,每个要点尽量 1-2 行,适合手机阅读。 8. 重要公司、行业、产品关键词请加粗。 建议输出骨架: # 统一归档检索摘要 ## 检索结论 ## 时间线 / 重点更新 ## 行业 / 标的归类 ## 边际变化 ## 来源分布 ## 待验证 下面是命中的原文片段: {evidence} """Technical Analysis
Content retrieved from the local archives is inserted directly into the language-model prompt through the
evidencevariable. Although each content field is truncated to 600 characters, the code does not:- Clearly delimit archive content as untrusted data.
- Tell the model to ignore instructions embedded in retrieved documents.
- Encode the evidence in a structured format that separates data from instructions.
- Validate the generated response against the expected report structure.
- Detect likely prompt-injection phrases in retrieved content.
Consequently ...[truncated 1639 chars]
- Remediation
View remediation
Remediation Suggestions
- Add an explicit instruction before the evidence stating that all retrieved text is untrusted data and that any commands or policy instructions inside it must be ignored.
- Wrap every archive record in strong, unique delimiters and label each field explicitly.
- Prefer structured serialization such as JSON and instruct the model to interpret serialized values only as source material.
- Pre-screen retrieved records for common prompt-injection patterns and either exclude, flag, or isolate suspicious records.
- Validate the generated response to ensure that it contains the required sections and does not introduce unsupported links or claims.
- Require important conclusions to cite specific source identifiers and verify that each conclusion is supported by the corresponding retrieved text.
- Use a non-agentic summarization context without tool permissions so that a successful injection cannot trigger external actions.
- Add regression tests using archive records that contain adversarial instructions.
