Back to skill

Security audit

unisound-common-disease-advice

Security checks for vulnerabilities and agentic risk

Overview

This medical advice skill is coherent in purpose, but it sends sensitive patient information to a remote model while promising de-identification that the code does not perform.

Review before installing or using with real patients. Do not provide names, IDs, phone numbers, exact addresses, medical record numbers, or other identifiers unless the skill is changed to perform local de-identification and you have approval for the remote endpoint's data handling. Treat all generated diagnoses, medication doses, and referral recommendations as untrusted decision support requiring clinician review.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.py:123
Finding

Patient Data Is Transmitted Without the Promised De-identification

Content
View full analysis
int: prompt = f"""请根据以下患者信息,给出常见病诊疗建议。 【患者信息】 {patient_info.strip()} 请严格按照要求输出 JSON + 摘要。""" print("正在分析患者信息并生成诊疗建议...") result = llm([sys_msg(SYSTEM_PROMPT), user_msg(prompt)]) ``` The relevant documentation states that identifiable information will be de-identified before being sent to any model or API. However, the implementation does not contain identifier detection, redaction, pseudonymization, or filtering logic. ### Technical Analysis `load_input()` accepts arbitrary text or JSON-based patient records and returns their content without modification. `run_advice()` then interpolates the complete value of `patient_info` into the LLM prompt. The resulting prompt is sent through `make_llm_caller()` to the configured `/chat/completions` endpoint. Consequently, names, telephone numbers, government identifiers, detailed addresses, medical record numbers, and other protected health information present in the input may be transmitted to a remote service verbatim. This behavior directly conflicts with the documented guarantee of strict de-identification. The use of HTTPS protects the transport channel against ordinary passive interception, but it does not prevent the receiving API operator from obtaining the unredacted data. The caller-controlled `--base` option can also redirect transmission to a different endpoint when an unsafe or incorrect base URL is supplied. ### Attack Path 1. A patient-information file contains clinical data together with direct identifiers. 2. `load_input()` reads and returns the record without sanitization. 3. `run_advice()` inserts the entire record into the prompt using `patient_info.s ...[truncated 870 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.py:123
Finding

Untrusted Patient Records Can Inject Instructions into the Medical LLM Prompt

Content
View full analysis
int: prompt = f"""请根据以下患者信息,给出常见病诊疗建议。 【患者信息】 {patient_info.strip()} 请严格按照要求输出 JSON + 摘要。""" print("正在分析患者信息并生成诊疗建议...") result = llm([sys_msg(SYSTEM_PROMPT), user_msg(prompt)]) # 分离 JSON 和摘要 json_part = "" summary_part = "" if "【摘要】" in result: idx = result.index("【摘要】") json_part = result[:idx].strip() summary_part = result[idx:].strip() else: json_part = result # 验证 JSON 可解析 parsed_json = None try: # 提取 JSON 块(可能包含 markdown 代码块) if "```" in json_part: start = json_part.find("{") end = json_part.rfind("}") + 1 json_part = json_part[start:end] parsed_json = json.loads(json_part) ``` ### Technical Analysis Patient records are untrusted input, but the implementation directly concatenates them into an instruction-bearing user message. There is no separation between clinical data and instructions found inside that data, and the system prompt does not explicitly require the model to treat embedded directives as untrusted record content. A crafted record can therefore include text instructing the model to ignore the required clinical rules, change referral decisions, recommend a particular medication, omit warnings, or generate misleading output. The response control only attempts to parse the result with `json.loads()`. JSON syntax validation does not validate: - Required keys - Field types - The maximum number of diagnoses - Permitted probability values - Medication safety - Referral consistency - The presence of warnings for red-flag symptoms - Whether the output was influenced by instructions embedded in the patient record A malicious response that r ...[truncated 1560 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script sends raw patient information to a remote LLM endpoint via run_advice(patient_info, llm, ...) without any built-in consent notice, privacy warning, minimization, or de-identification step. In a medical context this is especially sensitive because symptom narratives may contain personally identifiable and protected health information, creating confidentiality, regulatory, and data-handling risks if operators use the tool without understanding the external transmission.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill describes capabilities to read input files, write output files, and make outbound network requests to a remote medical-model API, but it does not declare any explicit tool scope such as permissions or allowed-tools. That mismatch weakens least-privilege controls and makes it harder for a platform to constrain what the skill may access, especially given the handling of sensitive patient data and external transmission.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The file's natural-language instructions, prompts, and output format are entirely fixed in Chinese, which imposes a specific language/locale on users. The file does not offer an opt-in language choice or explain that the skill is intentionally restricted to a Chinese-language regional context.

Content

No source excerpt is available for this finding.