Back to skill

Security audit

unisound-med-synonym

Security checks for vulnerabilities and agentic risk

Overview

The skill performs a disclosed medical LLM task, but it can send medical questions and the bearer API key to any caller-supplied API URL without validation.

Install only if you trust the operator and endpoint configuration. Do not pass real patient identifiers, prefer the documented HTTPS endpoint, avoid untrusted `--api-url` values, and treat the command-line API key as sensitive because it is forwarded to the configured endpoint.

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:65
Finding
Arbitrary API Endpoint Allows Bearer Credential and Medical Data Disclosure<![CDATA[ ## Vulnerability Details **File Location**: `scripts/run.py:65-83` (credential transmission sink); `scripts/run.py:213` (user-controlled endpoint source) **Vulnerability Type**: Unrestricted sensitive-data destination / credential disclosure **Risk Level**: High ### Vulnerable Code The API endpoint is accepted directly from a command-line argument without validation: ```python p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI 兼容接口地址") ``` The supplied endpoint then receives the bearer credential and medical question: ```python payload = { "model": model, "temperature": temperature, "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}, ], } try: 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) body = json.loads(resp.read().decode("utf-8")) ``` ### Technical Analysis The `--api-url` argument is unrestricted and flows into `urllib.request.Request` as the request destination. The request always includes the caller-provided API key in an `Authorization: Bearer` header and includes the complete question in its JSON body. No validation enforces HTTPS, checks the destination hostname against an allowlist, prevents requests to local or private-network addresses, or requires separate credentials when a custom provider is selected. Consequently, any party capable of influencing the script's invocation arguments can redirect sensitive information to an endpoint under its control. A plaintext `http://` endpoint can also expose the credential and medical content to network observers. This is not merely generic configurable networking: the same production credential intended for the documented service is automatically forwarded to t ...[truncated 1854 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. **Prefer a fixed endpoint** - Remove `--api-url` if alternate providers are not a genuine operational requirement. - Send the production key only to the documented HTTPS service. 2. **Enforce an explicit destination allowlist** - Parse the URL with `urllib.parse.urlsplit`. - Require the `https` scheme. - Reject embedded credentials, fragments, unexpected ports, and malformed hostnames. - Compare the normalized hostname against an exact allowlist such as `maas-api.hivoice.cn`; do not rely on substring or suffix checks. 3. **Separate credentials by provider** - Never forward the key for the default service to custom endpoints. - If custom providers must be supported, require a separately named credential explicitly associated with the selected provider. 4. **Restrict redirects** - Disable redirects or validate every redirect target before following it. - Ensure authorization headers are never sent to a different origin. 5. **Prevent internal-network targeting** - Resolve the hostname and reject loopback, link-local, private, multicast, reserved, and metadata-service addresses. - Revalidate resolved addresses when connecting to reduce DNS rebinding risk. - Apply outbound network controls so the process can reach only approved API hosts. 6. **Protect secret handling** - Read the API key from a protected environment variable, secret manager, or descriptor-based input rather than a command-line argument, because command-line values may be visible in process listings or execution logs. - Redact authorization data from logs and error reporting. - Rotate any credential that may already have been sent to an untrusted endpoint. 7. **Add security tests** - Verify rejection of `http://` URLs, unapproved domains, deceptive hostnames, localhost, private IP addresses, and cross-origin redirects. - Verify that the approved endpoint remains functional and receives credentials only ove ...[truncated 20 chars]
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Lp3

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding
The skill documentation exposes capabilities that imply local file access, file output, and outbound network calls, but it does not declare any explicit tool scope or permissions boundary. This is dangerous because integrators and users may invoke the skill without understanding that provided inputs can be read from arbitrary paths and transmitted to an external API, weakening least-privilege and review controls.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs callers to send medical question content to an external model API but does not give a clear warning that the content leaves the local environment or that sensitive medical data may be exposed in transit or at the third-party service. In a medical context, this is especially risky because prompts may contain protected health information or other regulated data, and the current wording only gives a general compliance note rather than explicit transmission and privacy disclosure.

Natural-Language Policy Violations

Medium
Confidence
96% confidence
Finding
The default system prompt is hard-coded entirely in Chinese and instructs the model how to answer, effectively imposing a specific language/locale behavior on all requests unless the caller overrides it. This is a natural-language policy concern because the file does not offer an explicit user language choice or opt-in for Chinese output.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
This skill sends user-supplied medical questions directly to a remote API endpoint, and medical prompts may contain protected health information or other sensitive data. Because the script provides no explicit warning, consent step, redaction, or minimization before transmission, operators can unintentionally disclose sensitive medical content to an external service.

Static analysis

No suspicious patterns detected.