T01 · Skill Instruction Hijacking
Error
- Location
- scripts/zoodata.py:910
- Finding
- Untrusted Amazon Review Content Is Embedded Directly into Agent Instructions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/zoodata.py:910-951` **Related Workflow**: `SKILL.md:197-216` **Vulnerability Type**: Prompt injection through untrusted review content **Risk Level**: High ### Vulnerable Code ```python def render_review_map_prompt(review: dict, product_title: str = "", product_category: str = "") -> str: title = review.get("title") or "" body = review.get("body") or "" full = f"{title}. {body}" if title else body text = full[:500] rating = review.get("rating") or 3 verified = bool(review.get("verifiedPurchase")) return f"""IMPORTANT: Respond ONLY with a JSON object matching the schema below. Output must be in English — translate non-English text before extracting. You are an expert data extraction specialist analyzing product reviews. Extract only what is EXPLICITLY mentioned — do not infer. JSON schema: {{ "sentiment": "positive" | "neutral" | "negative", "mentioned_scenarios": [string], "mentioned_issues": [string], "mentioned_positives": [string], "mentioned_improvements": [string], "mentioned_buying_factors": [string], "mentioned_pain_points": [string], "user_profiles": [string], "mentioned_usage_times": [string], "mentioned_usage_locations": [string], "mentioned_behaviors": [string], "keywords": [string] }} Rules: - sentiment: positive (4-5 stars or praise), neutral (3 stars / mixed), negative (1-2 stars or complaint) - pain_points = problems EXPERIENCED AFTER USE. NOT problems the product solves. - issues vs pain_points: issues = product defects; pain_points = UX frustrations - user_profiles: include ONLY if the reviewer explicitly states an identity - consistent naming across reviews - use empty arrays [] for categories with no mentions, never null INPUT: Product Category: {product_category or '(unknown)'} Product Title: {product_title or '(unknown)'} Review Rating: {rating}/5 stars Verified Purchase: {'Yes' if verified else 'No'} Review Text: \"\"\ ...[truncated 2428 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every API-provided review field as untrusted data. 2. Pass review content through a structured model input or tool-result channel instead of concatenating it into an instruction string. 3. Serialize review data as JSON and clearly identify it as inert data: ```python review_payload = json.dumps({ "title": title, "body": body, "rating": rating, "verifiedPurchase": verified, }, ensure_ascii=False) ``` 4. Add explicit model instructions stating that commands, policies, schemas, or role changes found inside review data must never be followed. 5. Avoid delimiter schemes that untrusted text can terminate. If textual delimiters remain necessary, encode or escape delimiter sequences before interpolation. 6. Validate generated output against `REVIEW_MAP_SCHEMA`, reject unknown fields, enforce array and string limits, and verify that extracted phrases are supported by the source review. 7. Apply analogous protections to candidate phrases passed into `render_review_reduce_prompt()`, because those phrases originate from earlier processing of untrusted reviews. 8. Add adversarial tests covering embedded triple quotes, fake system messages, requests to ignore prior instructions, and malformed JSON payloads. ]]>
