Back to skill

Security audit

unisound-med-clinical-diagnosis

Security checks for vulnerabilities and agentic risk

Overview

This medical helper is mostly purpose-aligned, but it can send sensitive clinical questions and a bearer key to any configured API endpoint and echoes raw questions in output.

Review before installing or using with real patient data. Use only de-identified questions, avoid passing PHI on the command line, keep outputs out of logs and shared artifacts, and do not override --api-url unless the endpoint is trusted and HTTPS-protected with a key intended for that destination.

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:96
Finding

Unrestricted API Endpoint Can Exfiltrate Credentials and Clinical Data

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:96-107, scripts/run.py:214, scripts/run.py:276-284
Vulnerability Type: User-controlled outbound destination with sensitive authorization and clinical data
Risk Level: Medium

Vulnerable Code

python
def call_llm(
    *,
    api_url: str,
    model: str,
    appkey: str,
    system_prompt: str,
    user_prompt: str,
    temperature: float,
    timeout: int,
) -> str:
    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)

The destination is exposed as an unrestricted command-line option:

python
p.add_argument("--api-url", default=DEFAULT_API_URL, help="OpenAI compatible endpoint URL")

The user-controlled value and sensitive data are subsequently passed into the request:

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 argument directly controls the destination supplied to urllib.request.Request. No validation restricts the URL scheme, destination hostname, port, or redirect target.

Every request to this destination contains:

  • The application key in the Authorization: Bearer header.
  • The complete clinical question in the JSON request body.
  • The system prompt and model configuration.
  • Potentially identifiab ...[truncated 1678 chars]
Remediation
View remediation

Remediation Suggestions

  1. Restrict permitted endpoints

    • Remove --api-url in production when endpoint customization is unnecessary.
    • Otherwise, maintain an explicit allowlist of trusted HTTPS hostnames and ports.
    • Parse the URL with urllib.parse.urlparse and reject unapproved schemes, hosts, ports, embedded credentials, fragments, and malformed values.
  2. Require transport security

    • Accept only the https scheme.
    • Reject plaintext HTTP even for user-supplied endpoints.
    • Preserve normal TLS certificate and hostname verification.
  3. Control redirects

    • Disable redirects for authenticated requests or validate every redirect destination against the same allowlist.
    • Never forward the Authorization header to a destination that has not been independently approved.
  4. Limit credential exposure

    • Use destination-specific, short-lived credentials with minimum permissions and restrictive quotas.
    • Do not reuse a production key when testing custom endpoints.
    • Consider retrieving credentials from a protected secret source rather than exposing them in process command-line arguments.
  5. Protect clinical information

    • Require de-identification before transmission.
    • Minimize request data to fields required by the service.
    • Record the approved destination in security logs without logging the bearer credential or clinical request body.
  6. Validate response provenance

    • Treat responses from non-default or development endpoints as untrusted.
    • Clearly identify the selected endpoint in operator-visible output and require explicit confirmation before sending sensitive data to a non-production service.
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 documentation exposes capabilities that imply file read, file write, and network access, but it does not declare any tool scope or permissions boundary. In an agent environment, this can cause the skill to run with broader-than-expected authority, increasing the chance of data exfiltration, unintended file access, or unsafe outbound requests if invoked on sensitive inputs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest description and the entire user-facing documentation are written only in Chinese, and the skill title and examples indicate a Chinese-only interaction pattern without any opt-in or language-selection guidance. Under the policy, forcing a specific language or locale without user choice is a natural-language policy concern unless the restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The system prompt is written to enforce Chinese-language medical-answer behavior, and the overall CLI description and messages are also fixed in Chinese. There is no opt-in, language selection, or documented justification that this skill is intentionally limited to a Chinese locale or user base.

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-supplied clinical questions to an external HTTPS API, and those questions may contain protected health information or other sensitive medical details. The skill description and runtime behavior provide no consent flow, warning, redaction step, or data-minimization control before transmission, which is especially risky in a medical-diagnosis context where inputs commonly contain highly sensitive patient data.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The program includes the original question and metadata in its output structure and can write them to files or stdout during normal operation. In a clinical setting, this creates a substantial risk of leaking sensitive patient information into logs, shell history captures, redirected files, CI artifacts, or downstream systems that consume the output.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.