Back to skill

Security audit

unisound-pmh-missing-bp-glucose

Security checks for vulnerabilities and agentic risk

Overview

The skill largely matches its stated medical-record quality-control purpose, but users should review it because it sends clinical text to a remote model and can persist prepared medical records despite a no-persistence statement.

Install only if your organization has approved sending de-identified medical-record text to the configured MaaS provider. Do not use --save-prepared with real patient records unless the output directory is secured and retention is planned, and treat QC results as requiring clinician review rather than authoritative decisions.

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

Warning
Location
scripts/emr_qc_impl.py:117
Finding

Untrusted Medical Record Content Can Manipulate LLM Quality-Control Results

Content
View full analysis
str: """既往史缺血压血糖控制情况""" pmh = fields["pmh"] if not pmh: return "无缺陷" # LLM1:既往史中是否已包含用药/控制相关关键词(快速判断) has_keywords = llm([user_msg( f"""给定门诊病历中既往史字段,请判断其中是否包含"降糖药","降压药","控制血糖","控制血压"或者相关的描述,请直接回答"是"或者"否" 既往史:{pmh}""" )]) # 若已包含控制信息关键词,则跳过完整质控 if "是" in has_keywords and "否" not in has_keywords: return "无缺陷" # 完整质控 return llm([user_msg( f"""你是一位病历质控专家,请对门诊病历进行质控,如果没有缺陷请直接回答"无缺陷",不要进行任何分析;如果有缺陷请先回答"有缺陷"再另起一行分析原因 缺陷描述: 1.既往史中记录高血压,但是没有记录血压控制情况 2.既往史中描述糖尿病,但是没有记录血糖控制情况 请注意,控制情况包含但不限于以下几种 - 血糖有具体数值mmol/L,血压有具体数值和mmgh - 控制尚可 - 控制可 - 未监测 - 控制良好 - 控制不佳 - 轻度异常 - 波动明显 - 稳定 - 有记录 - 有症状 - 治疗效果不佳 - 随访中 以下是一些示例,用标记,请参考 【病历】 既往史:高血压病史10年,长期口服缬沙坦。 【质控结果】 有缺陷 有高血压病史,但是没有记录血压情况 【病历】 既往史:高血压病史10年,长期口服吲达帕胺,近期血压140/90mmgh 【质控结果】 无缺陷 【病历】 既往史:高血压病史年,口服药物治疗,控制良好;糖尿病病史年,口服药物/注射胰岛素治疗,控制良好 【质控结果】 无缺陷 【病历】 既往史:糖尿病史:10年,药物控制,控制不佳 【质控结果】 无缺陷 现在请对下面的门诊病历进行质控 【病历】 既往史:{pmh} 【质控结果】""" )]) ``` ### Technical Analysis The `pmh` value originates from the supplied medical record and is therefore untrusted. It is interpolated directly into the same user-role message that contains the operational quality-control instructions. No structural separation or explicit trust boundary prevents instructions embedded in the medical record from being interpreted as model directives. An attacker can place text in the past-medical-history field instructing the model to ignore the preceding rule and return a chosen result. Both LLM calls are affected: 1. The preliminary response is interpreted using a weak substring test: ```python if "是" in ...[truncated 1825 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:105
Finding

Optional Debug Feature Persists Sensitive Medical Records in Plaintext

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sends patient medical-history text directly to a remote LLM service over the network without any visible consent, warning, minimization, or policy gate. Because the data is outpatient EMR content and may contain sensitive health information, this creates a real privacy and compliance risk if operators assume processing is local or if the remote provider retains, logs, or further processes submitted data.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill documentation indicates capabilities for file read, file write, and network access, but it does not declare any explicit tool scope or permission boundaries. In a skill that processes medical records and calls an external API, this omission increases the risk of overbroad access, accidental data exfiltration, or misuse of local files because the runtime cannot enforce least privilege from the manifest.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown requires outpatient records to use Chinese labels such as 主诉、现病史、既往史 and states the expected input format in Chinese, but it does not indicate that this is an optional locale mode or offer alternatives. Under the policy, forcing a specific language or locale without user opt-in is a natural-language policy violation unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The module docstring and all prompt/instruction text are written exclusively in Chinese, which imposes a specific language on users and downstream model interactions. There is no indication that users can choose another language or that the Chinese-only behavior is a documented, justified locale constraint.

Content

No source excerpt is available for this finding.

Ssd 1

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Untrusted EMR text is interpolated directly into natural-language prompts, so a crafted patient-history field can inject instructions such as telling the model to ignore the QC task or emit attacker-chosen output. In this skill, the model's response directly determines whether a chart is flagged as defective, so prompt injection can suppress findings or produce incorrect medical quality-control results.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The function creates an output directory and writes the QC result to a file, which is a file-write operation affecting user data and filesystem state. Although a success message is printed after writing, there is no prior warning, confirmation, or descriptive docstring/comment explaining that results will be persisted to disk by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The file uses Chinese-only natural-language descriptions in the module docstring, and the CLI help continues this pattern, which can amount to a language policy constraint if users are not given an explicit language or locale choice. Under SQP-3, forced language without opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.