Back to skill

Security audit

unisound-paper-writing-assist

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it says, but it sends clinical research notes to an external model service and handles the API key in a way users should review carefully.

Review this skill before installing if your notes may contain patient identifiers, protected health information, unpublished research data, or institution-confidential details. Use only data you are authorized to send to the listed external model service, prefer de-identified notes, and avoid putting a real API key directly on the command line when possible.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:111
Finding

API credential exposed through command-line arguments

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:111-115 (credential use also occurs at scripts/run.py:39-43; insecure invocation is documented at SKILL.md:29-31)
Vulnerability Type: Exposure of a secret through process arguments
Risk Level: Medium

Evidence

scripts/run.py:39-43:

python
def call_llm(system: str, user: str, appkey: str) -> str:
    payload = {"model": MODEL, "temperature": 0.0, "messages": [
        {"role": "system", "content": system},
        {"role": "user", "content": user},
    ]}
    body = _http_post(API_URL, payload, {"Authorization": f"Bearer {appkey}"})

scripts/run.py:111-115:

python
    parser.add_argument(
        "--appkey",
        required=True,
        help="内部医疗大模型鉴权 key。",
    )

SKILL.md:29-31:

bash
python3 scripts/run.py --input input.json --output output.json --appkey YOUR_KEY

Technical Analysis

The application requires the API credential to be passed in the --appkey command-line argument. Command-line arguments are not an appropriate secret transport mechanism because they can be exposed through shell history, process inspection facilities, job-runner logs, audit records, crash diagnostics, monitoring systems, or command transcription.

The supplied value is subsequently used as a bearer credential in the HTTP Authorization header. Therefore, disclosure of the command-line value directly discloses a reusable authentication secret rather than a non-sensitive identifier.

HTTPS protects the credential while it is transmitted to the configured API endpoint, but it does not mitigate exposure that occurs locally before the request is sent.

Attack Path

  1. A user follows the documented command and supplies a valid API key through --appkey.
  2. The complete command is retained in shell history, recorded by an automation platform, or temporarily exposed through operating-system process inspecti ...[truncated 1074 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove the required secret-bearing --appkey argument.
  2. Read the credential from a protected environment variable or a dedicated secret manager. Avoid printing the value or including it in exception messages.
  3. For interactive use, optionally support a non-echoing prompt through getpass.getpass() when no managed secret is available.
  4. Update SKILL.md so its examples do not place a real credential in the command line.
  5. Configure short-lived, narrowly scoped credentials and provider-side quota restrictions.
  6. Document credential rotation and immediately revoke keys suspected of having appeared in shell history or logs.
  7. If backward compatibility requires retaining --appkey, clearly mark it as deprecated and emit a warning without including the supplied value.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:39
Finding

Potential disclosure of identifiable clinical data to an external model service

Content
View full analysis

Vulnerability Details

File Location: scripts/run.py:39-43 and scripts/run.py:77-89
Vulnerability Type: External transmission of potentially sensitive clinical notes without a privacy safeguard
Risk Level: Medium

Evidence

scripts/run.py:39-43:

python
def call_llm(system: str, user: str, appkey: str) -> str:
    payload = {"model": MODEL, "temperature": 0.0, "messages": [
        {"role": "system", "content": system},
        {"role": "user", "content": user},
    ]}
    body = _http_post(API_URL, payload, {"Authorization": f"Bearer {appkey}"})

scripts/run.py:77-89:

python
    user = f"""目标章节:{section}
写作语言:{"中文" if lang == "zh" else "English"}

要点列表:
{chr(10).join(f"- {n}" for n in notes)}

{f"期刊 / 风格提示:{journal}" if journal else ""}

请输出该章节的连贯草稿(可适当分子标题),并附写作自检 bullet。"""

    text = call_llm(SYSTEM, user, appkey)

The destination is fixed at scripts/run.py:14:

python
API_URL = "https://maas-api.hivoice.cn/v1/chat/completions"

Technical Analysis

All values in notes, together with the section and optional journal-style hint, are inserted into the model prompt and sent to an external API. The application does not inspect, redact, pseudonymize, or block patient identifiers before transmission. It also does not require the user to confirm that external processing is authorized.

Because the skill is explicitly intended for clinical research writing, its inputs may plausibly include protected health information, patient identifiers, unpublished research data, or other confidential material. TLS protects data in transit against ordinary network interception, but the external service still receives the plaintext content and may process or retain it according to its own policies.

The documentation identifies the endpoint, so the network communication itself is not hidden. The security concern is the absence of safeguards and sufficiently explici ...[truncated 1662 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add a prominent warning that inputs are transmitted to an external model service and must not contain direct patient identifiers unless processing is explicitly authorized.
  2. Require affirmative confirmation before transmitting content classified as clinical or sensitive.
  3. Implement optional local de-identification that detects and removes common identifiers such as names, record numbers, contact details, exact dates, and account identifiers.
  4. Apply data minimization by sending only text necessary for the requested writing operation.
  5. Document the service provider, processing location where known, retention policy, training-use policy, deletion controls, and applicable contractual safeguards.
  6. Provide a configurable approved endpoint or a local-model option for organizations that prohibit third-party clinical-data processing.
  7. Add automated tests confirming that enabled redaction occurs before _http_post is called.
  8. Ensure application and infrastructure logs do not record request bodies, prompts, authorization headers, or raw clinical notes.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • 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
88% confidence
Finding

The skill declares executable behavior and references a script invocation with an external API endpoint plus input/output file paths, but it does not declare any explicit tool scope or permissions. This creates an authorization and transparency gap: a host agent may permit file and network operations more broadly than intended, increasing the risk of unintended data access or exfiltration, especially in a medical-writing context where notes may contain sensitive research or patient-related information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sends user-provided research notes to an external API endpoint, and those notes may contain unpublished study details, patient-adjacent clinical information, or other sensitive research material. In a medical-writing context this is more dangerous because confidentiality, regulatory obligations, and institutional data-handling requirements are stricter; the code provides no visible disclosure, consent gate, redaction step, or policy enforcement before exfiltrating the content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code sets the default language to "zh" and forces any unrecognized language value back to Chinese rather than preserving user choice or asking for confirmation. This is a natural-language policy concern because it imposes a locale/language behavior without explicit opt-in.

Content

No source excerpt is available for this finding.

Tainted flow: 'text' from pathlib.Path.read_text (line 121, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/run.py (reported line 125)May include surrounding context.

python
if args.output:
            p = Path(args.output)
            p.parent.mkdir(parents=True, exist_ok=True)
            p.write_text(text, encoding="utf-8")
        else:
            print(text, end="")
        return 0

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The markdown states that language is optional and defaults to zh, which imposes a specific locale when the user does not explicitly choose one. This is a natural-language policy concern because the skill forces a language preference by default rather than requiring or clearly requesting user selection.

Content

No source excerpt is available for this finding.