T01 · Skill Instruction Hijacking
Warning
- Location
- SKILL.md:42
- Finding
- Untrusted Web Content Is Passed Directly into the Agent Context<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:42-43`, `scripts/main.py:31-35, 82-90`, `scripts/fetch_and_store.py:48-52, 108-119, 238-244` **Vulnerability Type**: Indirect prompt injection through externally controlled article content **Risk Level**: Medium ### Vulnerable Code The Skill instructs the Agent to process all article content returned by the crawler: ```markdown ### Step 2: LLM 总结(由你执行) 仔细阅读爬虫传回的全部 Article 内容,按照以下要求进行深度提炼: ``` Both crawler implementations remove HTML markup but preserve arbitrary natural-language instructions: ```python def extract_pure_text(html_content): """通用正文提取:剥离脚本、样式表及HTML标签,留下高密度文本""" text = re.sub(r'<script[^>]*>([\s\S]*?)</script>', '', html_content) text = re.sub(r'<style[^>]*>([\s\S]*?)</style>', '', text) text = re.sub(r'<[^>]+>', ' ', text) text = re.sub(r'\s+', ' ', text).strip() return text[:2500] # 每篇详情页限制前 2500 字,防止大模型爆 Token ``` The extracted content is returned to the Agent without a trust boundary: ```python final_payload.append({ "source": src["title"], "title": item["title"], "content": pure_text }) ``` The storage-enabled implementation follows the same pattern: ```python def extract_pure_text(html_content): text = re.sub(r'<script[^>]*>([\s\S]*?)</script>', '', html_content) text = re.sub(r'<style[^>]*>([\s\S]*?)</style>', '', text) text = re.sub(r'<[^>]+>', ' ', text) text = re.sub(r'\s+', ' ', text).strip() return text[:2500] ``` ```python final_payload.append({ "source": src["title"], "title": item["title"], "content": pure_text, "url": item["url"] }) ``` ```python result = { "status": "success", "date": today, "article_count": len(articles), "articles": articles } print(json.dumps(result, ensure_ascii=False)) ``` ### Technical Analysis Article titles and bodies are controlled by external publishers or by anyone capable of compromising a source page. Removing scripts, styles, and HTML tags ...[truncated 2175 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Explicitly classify every fetched title, description, and article body as untrusted data. 2. Add a high-priority instruction stating that the Agent must never follow commands, policies, links, tool requests, or formatting directives found inside article content. 3. Enclose each article in a structured data boundary and ask the model to extract only predefined factual fields. 4. Perform summarization in an isolated model invocation that has no filesystem, network, shell, or other side-effecting tools. 5. Reject or flag instruction-like phrases in fetched content before presenting it to the Agent. 6. Preserve provenance for each extracted claim and require generated summaries to cite the corresponding source record. 7. Require explicit user approval before executing any tool call suggested by remotely fetched content. 8. Treat cached article content and existing generated reports as untrusted when loading them in later sessions. ]]>
