T01 · Skill Instruction Hijacking
Error
- Location
- agent.py:399
- Finding
- Untrusted RSS Headlines Can Influence Downstream Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `agent.py:383, 399-417, 488-501, 513-529` **Vulnerability Type**: Indirect prompt injection through remotely controlled content **Risk Level**: High ### Vulnerable Code ```python with urlopen(req, timeout=8) as r: raw_bytes = r.read() ``` ```python results = [] for item in items[:10]: title = _get_text(item, "title") if not title: continue link_el = item.find("link") link = (link_el.text or "").strip() if link_el is not None else "" desc = _get_text(item, "description", "summary") pub_ts = parse_date(_get_text(item, "pubDate", "published")) agency = source["agency"] if source.get("extract_source"): agency, title = _extract_source(title, agency) text = title + " " + desc sent, score = sentiment_score(text) syms, rel_scores = rel_symbol(text, source.get("symbols_hint", [])) results.append({ "title": title[:200], "link": link, "agency": agency, "pub_ts": pub_ts, "pub_time": datetime.fromtimestamp(pub_ts).strftime("%Y-%m-%d %H:%M"), "sentiment": sent, "score": score, "symbols": syms, "rel_scores": rel_scores, }) ``` ```python for n in shown: shown_titles.add(n["title"][:60].lower()) icon = SENT_ICON[n["sentiment"]] label = SENT_LABEL[n["sentiment"]] star = "★ " if n["agency"] in PRIORITY_AGENCIES else " " lines.append(f" {star}{icon} [{label}] {n['title'][:80]}") lines.append(f" 来源: {n['agency']} 时间: {n['pub_time']}") if n.get("link"): lines.append(f" 链接: {n['link'][:100]}") ``` ```python for n in shown: icon = SENT_ICON[n["sentiment"]] label = SENT_LABEL[n["sentiment"]] star = "★ " if n["agency"] in PRIORITY_AGENCIES else " " syms_str = " / ".join(n.get("symbols", [])) lines.append(f" {star}{icon} [{label}] {n['title'][:80]}") lines.append(f" 来源: {n['agency']} 时间: {n['pub_time']} 品种: {syms_str}") if n ...[truncated 2472 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Return news as structured data with explicit fields such as `untrusted_title`, `source`, and `link`, rather than mixing it into instructional prose. 2. Add a trusted instruction outside the remote data stating that feed content is untrusted and must never be followed as commands. 3. Place remote fields inside strong delimiters and clearly identify the beginning and end of each untrusted value. 4. Strip control characters, bidirectional text controls, and other characters that can obscure data boundaries. 5. Apply prompt-injection detection as defense in depth, while not relying on keyword filtering as the primary control. 6. Prevent remote content from triggering tools or privileged operations without an independent trusted decision and explicit authorization. 7. Preserve source provenance so downstream consumers can distinguish skill-authored text from third-party content. ]]>
