T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/run.py:95
- Finding
- Prompt Injection Through Untrusted Patient Data<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py`, lines 95–108 **Vulnerability Type**: Prompt injection caused by directly interpolating untrusted data into an LLM prompt **Risk Level**: Medium ### Vulnerable Code ```python user_prompt = f"""请为以下患者生成复诊提醒: 疾病类型:{disease_type} 上次就诊:{last_visit_date_str} 复诊日期:{followup_date.isoformat()} 当前日期:{today.isoformat()} 是否逾期:{'是,已逾期' + str(days_overdue) + '天' if is_overdue else '否,还有' + str(-days_overdue) + '天'} 备注:{note} 请分析风险并给出复诊建议和准备清单。""" text = _call_llm(SYSTEM_PROMPT, user_prompt, appkey) ``` ### Technical Analysis The application inserts the attacker-controllable `disease_type`, `last_visit_date_str`, and `note` values directly into an instruction sent to the language model. These values are not isolated as untrusted data, constrained by length, or validated for instruction-like content. An attacker can place additional model instructions in the `note` field, such as directions to ignore the intended task, generate misleading medical guidance, include an attacker-controlled link, or omit the required disclaimer. Because the generated response is accepted as an unrestricted string and returned in the `text` field, the application has no deterministic mechanism for detecting whether the model followed injected instructions. This issue affects output integrity rather than local operating-system execution. The date calculation remains local and deterministic, but the natural-language medical reminder can be manipulated. ### Attack Path 1. An attacker creates an otherwise valid input document or JSON object. 2. The attacker places adversarial model instructions in `note`, `disease_type`, or another interpolated string field. 3. `build()` embeds that content into `user_prompt` without a trust boundary. 4. `_call_llm()` sends the combined instructions and patient data to the remote model. 5. The model may follow the embedded instructions instead of, or in addition to, the intended reminder ...[truncated 567 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Treat every parsed patient field as untrusted data and place it in a clearly delimited data structure, preferably a JSON object in a separate message. 2. Add an explicit system-level rule stating that content inside patient fields is data and that instructions contained within those fields must never be followed. 3. Validate field types and enforce strict maximum lengths before constructing the request. 4. Ask the model for a constrained JSON response with an explicit schema rather than unrestricted Markdown. 5. Validate the response against that schema and reject unexpected fields, URLs, active content, or missing safety language. 6. Generate critical medical boundaries and disclaimers locally rather than relying on the model to preserve them. 7. Sanitize the final response according to the rendering context, especially if Markdown links or embedded HTML can be displayed. 8. Keep deterministic values such as follow-up dates and overdue status authoritative; do not permit model output to override them. ]]>
