T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/run.py:145
- Finding
- Medical Reports Are Transmitted Without the Promised De-identification## Vulnerability Details **File Location**: `scripts/run.py:45-50, 145-147`; related privacy guarantee in `SKILL.md:25-29` **Vulnerability Type**: Sensitive medical information disclosure **Risk Level**: High ### Vulnerable Code ```python def llm(messages: List[Dict[str, str]]) -> str: payload = {"model": model, "messages": messages, "temperature": 0} resp = _http_post(url, payload, headers, timeout=timeout) try: return resp["choices"][0]["message"]["content"].strip() ``` ```python result = llm([sys_msg(SYSTEM_PROMPT), user_msg(prompt)]) ``` The `prompt` variable contains `report_text.strip()`, which is the complete report loaded from the input file. ### Technical Analysis The documentation states that directly identifying information will be de-identified before information is sent to any model or API. The implementation does not contain a redaction, tokenization, pseudonymization, or identifier-detection stage. The report is inserted into the user prompt without modification and passed to the LLM caller. The caller serializes the complete messages collection and sends it to the configured remote API. Consequently, names, identity numbers, telephone numbers, addresses, examination dates, patient identifiers, and sensitive medical findings can all be transmitted if they appear in the supplied report. This violates the documented privacy boundary and the data-minimization principle. It is especially significant because health records can contain both identifying information and highly sensitive medical data. ### Attack Path 1. A user supplies a health report containing personal identifiers and medical findings. 2. `load_input()` reads and returns the complete report without sanitization. 3. `run_overall_report()` embeds the unchanged report in the LLM prompt. 4. The prompt is passed to the `llm` closure. 5. The closure serializes the messages and transmits them to the remote completion API. 6. The remote service receives the identif ...[truncated 888 chars]
- Remediation
- ## Remediation Suggestions 1. Add a local de-identification stage before prompt construction. Detect and redact names, telephone numbers, email addresses, postal addresses, identity numbers, medical-record numbers, and other direct identifiers. 2. Apply data minimization by extracting only findings necessary for interpretation rather than sending the complete original report. 3. Validate the sanitized result before transmission and block the request when high-confidence identifiers remain. 4. Clearly inform users that medical data will be sent to a remote model and obtain explicit consent before transmission. 5. Update the documentation so that its privacy claims exactly match implemented behavior and residual risks. 6. Add automated tests containing representative identifiers and verify that none appear in the outgoing request payload. 7. Define retention and logging restrictions with the API operator, including suppression of request-body logging where supported. 8. Consider a locally hosted processing option for reports that cannot legally or contractually be disclosed to a remote service.
