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## 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
## 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## 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
## 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)

Lp3

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.

Missing User Warnings

Medium
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.

Natural-Language Policy Violations

Medium
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.

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

Medium
Category
Data Flow
Content
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
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.

Natural-Language Policy Violations

Low
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.

Static analysis

No suspicious patterns detected.