Back to skill

Security audit

unisound-drg-grouping

Security checks for vulnerabilities and agentic risk

Overview

This medical DRG helper is mostly coherent, but its configurable API endpoint could expose sensitive case text and the API key if misused.

Install only if you are comfortable sending DRG case text to the configured medical model endpoint. Use the documented default or another approved HTTPS endpoint, de-identify real patient data first, protect the appkey, and store --output files only where medical data is allowed to reside.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.py:81
Finding
Unrestricted API Endpoint Allows Credential and Medical Data Exfiltration<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py:81-89`, `scripts/run.py:215`, `scripts/run.py:253-259` **Vulnerability Type**: Arbitrary outbound endpoint, credential disclosure, sensitive-data exposure, and server-side request forgery **Risk Level**: High ### Vulnerable Code ```python req = Request( api_url, data=json.dumps(payload, ensure_ascii=False).encode("utf-8"), headers={ "Content-Type": "application/json", "Authorization": f"Bearer {appkey}", }, ) resp = urlopen(req, timeout=timeout) ``` The destination can be configured directly through a command-line argument: ```python p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI 兼容接口地址") ``` The unvalidated value is passed to the network request together with the API key and complete question: ```python out["answer"] = call_llm( api_url=args.api_url, model=args.model, appkey=args.appkey, system_prompt=args.system_prompt, user_prompt=user_prompt, temperature=float(args.temperature), timeout=int(args.timeout), ) ``` ### Technical Analysis The `--api-url` option accepts an arbitrary URL without validating its scheme, hostname, resolved address, port, or redirect destination. `call_llm()` sends an `Authorization: Bearer` header containing the supplied application key and a JSON request body containing the complete user prompt to this destination. An attacker who can influence the command invocation can therefore direct the request to an attacker-controlled server. The implementation also permits plaintext HTTP URLs, allowing credentials and medical data to be exposed to network observers. Because `urlopen()` supports HTTP redirects, redirect behavior introduces an additional destination-control risk unless redirects are disabled or every redirect target is independently validated. The same primitive can issue requests to loopback, private, link-local, or otherwise internal addresses. Although successful resp ...[truncated 2359 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove the `--api-url` option if endpoint customization is not required and always use the documented trusted endpoint. 2. If customization is necessary, enforce an explicit allowlist of approved HTTPS hostnames and ports. 3. Reject all non-HTTPS schemes to prevent plaintext transmission of credentials and medical data. 4. Resolve the destination hostname and reject loopback, private, link-local, multicast, reserved, and cloud metadata address ranges. Recheck the resolved address when connecting to reduce DNS rebinding risk. 5. Disable HTTP redirects or validate the scheme, hostname, port, and resolved address of every redirect target before following it. 6. Bind credentials to approved destinations. Do not attach the bearer token until the destination has passed validation. 7. Use narrowly scoped, short-lived credentials and establish rotation and revocation procedures for potentially exposed keys. 8. Require de-identification of patient information before transmission and minimize the medical data included in model prompts. 9. Add automated tests confirming rejection of HTTP URLs, unapproved domains, loopback addresses, private addresses, metadata endpoints, and redirects to unapproved hosts. 10. Consider enforcing outbound network policy outside the application so the process can communicate only with the approved model endpoint. ]]>
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)

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill manifest declares no explicit tool scope or permissions, yet the package description and detected capabilities indicate it can read files, write output files, and make network requests to an external model API. Without an allowlist in the manifest, a caller cannot easily constrain or audit those capabilities, increasing the risk of unintended data access or exfiltration when handling sensitive medical text.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
This skill sends raw user-supplied discharge summaries and related DRG question content to an external HTTPS API, and the data is likely to contain highly sensitive medical information. Even if the endpoint is described as an internal medical model, the script provides no minimization, consent prompt, masking, or transmission disclosure, so operators can unintentionally exfiltrate protected health information to a remote service.

Missing User Warnings

Low
Confidence
89% confidence
Finding
The script persists both the original question text and model answer to an output file, which can store sensitive discharge content on disk in plaintext. In a medical workflow this creates additional confidentiality and retention risk, especially if output paths point to shared directories, logs, or long-lived artifacts without any warning or access controls.

Static analysis

No suspicious patterns detected.