Back to skill

Security audit

unisound-med-content-generation

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it advertises, but it can send sensitive medical text and a bearer key to a configurable remote API without strong safeguards.

Review before installing. Use only with de-identified medical content, verify that the configured API endpoint is a trusted HTTPS service, avoid passing production keys to custom endpoints, and treat command-line app keys as sensitive. The skill appears coherent and not destructive, but its privacy and endpoint controls are weak for medical 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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:104
Finding

Unrestricted API Endpoint Can Receive Credentials and Sensitive Medical Content

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py, lines 104–117; related configuration at lines 214, 218, 223, and invocation at lines 275–282
Vulnerability Type: Arbitrary outbound endpoint, credential disclosure, sensitive-data exposure, and potential SSRF
Risk Level: Medium

Vulnerable Code

python
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"))

The endpoint and credential are accepted directly from command-line arguments:

python
p.add_argument("--appkey", default="", help="内部医疗大模型鉴权 key。")
p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI 兼容接口地址")

They are then passed to the network request without endpoint validation:

python
out["answer"] = call_llm(
    api_url=args.api_url,
    model=args.model,
    appkey=args.appkey,
    system_prompt=system_prompt_for(task_key, 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 and passes it directly to urllib.request.urlopen(). The code does not enforce HTTPS, restrict the destination to an approved hostname, reject embedded URL credentials, or block loopback, link-local, and private-network destinations.

Every request includes the user-supplied API key as a bearer credential. It also transmits the system prompt and the complete question, which may contain clinical records or other sensitive medical information.

Consequently, anyone who can influence the command-line configuration can redirect the request to an attacker-controlled server. A plaintext HTTP endpoint could also expose the request to network interception. If thi ...[truncated 1760 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict destinations to approved HTTPS endpoints

    • Parse the URL with urllib.parse.urlsplit.
    • Require the scheme to be exactly https.
    • Compare the normalized hostname against an explicit allowlist.
    • Reject URLs containing embedded usernames or passwords.
  2. Prevent SSRF

    • Resolve the destination hostname and reject loopback, link-local, private, multicast, reserved, and unspecified IP ranges.
    • Revalidate destinations after redirects, or disable redirects entirely.
    • Apply outbound firewall rules so the process can reach only approved API hosts.
  3. Protect credentials

    • Do not send a production API key when a custom endpoint is selected.
    • Consider removing --api-url from normal operation and exposing custom endpoints only through trusted administrative configuration.
    • Load credentials from a protected secret store or environment variable rather than command-line arguments, which may be visible through process inspection or shell history.
    • Use narrowly scoped, short-lived credentials and rotate any key suspected of exposure.
  4. Protect medical data

    • Require de-identification before transmission.
    • Log only destination metadata and request identifiers; never log bearer tokens or complete clinical prompts.
    • Document which approved external service receives the data and apply appropriate retention and access controls.
  5. Fail securely

    • Validate the endpoint before constructing the request.
    • Return a clear error for unapproved schemes or hosts.
    • Set explicit response-size limits and preserve the existing network timeout.
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 (5)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill declares no explicit tool scope or permission boundaries even though its documented behavior implies file reading, file writing, and outbound network access. In an agent ecosystem, missing capability declarations weakens reviewability and can lead to broader-than-expected access being granted or used without informed operator consent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The documentation instructs users to send medical questions and clinical documents to a remote medical LLM API, but the warning about sensitive data appears later and is not prominent at the transmission point. Because this skill handles clinical summaries, records, and teaching cases, users may unknowingly transmit PHI/PII or regulated health data off the local system, creating privacy, compliance, and data governance risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module description and core prompts are written to operate in Chinese, and the system prompt instructs the model entirely in Chinese. There is no indication that users may choose another language or that the Chinese-only behavior is a documented, necessary regional constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code sends user-provided medical questions, along with associated metadata and prompts, to a remote third-party API endpoint without any explicit consent flow, warning, redaction, or minimization. In a medical-content skill, inputs may contain protected health information or other sensitive personal data, so silent transmission creates a meaningful confidentiality and compliance risk even if the endpoint is an intended backend.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The natural-language instructions and examples are entirely in Chinese, and the file presents the skill as a general medical content generation tool rather than a clearly region-specific or Chinese-only skill. Under the stated policy, forcing a specific language without opt-in or justification can be a locale-policy issue.

Content

No source excerpt is available for this finding.