T09 · Insecure Skill Coding Practices
- Location
scripts/search_artifacts.py:55- Finding
Indirect Prompt Injection Through Untrusted Search Results
- Content
View full analysis
Vulnerability Details
File Location:
scripts/search_artifacts.py, lines 55–91
Vulnerability Type: Indirect prompt injection caused by untrusted search content being embedded directly into an LLM prompt
Risk Level: MediumVulnerable Code
python combined_content = "\n\n".join([ f"--- 搜索结果 {i+1} ---\n{result[:1500]}" for i, result in enumerate(search_results[:12]) ]) prompt = f""" 你是一位博物馆文物专家。请从以下{museum_name}的搜索结果中提取文物信息。 要求: 1. 只提取该博物馆的**常设馆藏文物**,排除借展、巡展、复制品、仿品 2. 提取文物名称、所属展馆、所属时期、文物种类、是否是镇馆之宝、简要描述 2. 时期必须从以下列表中选择:远古时期、夏商西周、春秋战国、秦汉、三国两晋南北朝、隋唐五代、辽宋夏金元、明清 3. 文物种类必须从以下列表中选择:青铜器、陶器、瓷器、漆器、玉器宝石、石器石刻、书画古籍、服饰、砖瓦、钱币、化石、金银器、其他 4. 关注的领域从以下列表中选择:农耕、狩猎、饮食、建筑、人物、武器、文房四宝、牌章证件、货币、书法、绘画、雕像、服装、饰品、仪器、佛教、乐器、纹饰、花瓶、礼制、古生物、新石器、旧石器、陈设品、科技、其他 5. 如果搜索结果中未提及展馆,请使用"待确认" 6. 尽可能多地提取文物(至少20件) 请返回JSON数组格式: [ {{ "name": "文物名称", "hall": "展馆名称", "period": "时期", "type": "文物种类", "is_treasure": true/false, "description": "简要描述", "domains": ["领域1", "领域2"], "child_friendly": true/false }} ] 搜索结果: {combined_content} """ try: result = call_llm_api(prompt)Technical Analysis
The application obtains passages from ProSearch and concatenates them into
combined_content. These passages are then interpolated directly into an instruction-bearing prompt and submitted to the configured LLM.Search results are attacker-influenceable data. A malicious or compromised indexed page can contain text framed as model instructions, such as directions to disregard the extraction rules, fabricate artifacts, return promotional content, or place attacker-controlled text in output fields. The prompt does not clearly isolate search passages as untrusted data, explicitly prohibit following instructions found within them, or identify their provenance.
The response is checked only to determine whether it is a list. Indivi ...[truncated 2027 chars]
- Remediation
View remediation
Remediation Suggestions
-
Establish an explicit trust boundary
- Mark every search passage as untrusted quoted data.
- Instruct the model that text inside search-result delimiters is evidence only and that any instructions contained there must be ignored.
- Use clear per-document delimiters and preserve source metadata separately.
-
Use structured model inputs where supported
- Place application instructions in a system or developer message.
- Place search passages in a separate user message or structured field rather than concatenating instructions and retrieved text into one prompt.
-
Validate every returned record
- Require an exact JSON schema.
- Reject unknown properties and incorrect data types.
- Enforce enumerations for
period,type, anddomains. - Set limits for field length and total record count.
- Reject records containing instruction-like language, unexpected Markdown, scripts, or URLs where those values are not required.
-
Verify provenance
- Prefer official museum websites and other allowlisted sources.
- Require source citations for extracted artifacts.
- Cross-check important claims against multiple independent sources before marking an artifact as a museum treasure or permanent exhibit.
-
Reduce attacker-controlled context
- Deduplicate results and remove irrelevant content.
- Strip page navigation, advertisements, and obvious prompt-injection patterns before invoking the model.
- Do not treat filtering alone as the primary defense, because malicious instructions can be phrased in many ways.
-
Fail safely
- If validation or provenance checks fail, discard the generated records rather than rendering them.
- Clearly label unverified online information and direct users to official museum sources.
-
