Back to skill

Security audit

unisound-medication-record-management

Security checks for vulnerabilities and agentic risk

Overview

This skill needs Review because it handles sensitive medication records through a mandatory external model call and has an unsafe fallback that can execute code outside the reviewed package.

Install only if you are comfortable sending medication names, doses, dates, statuses, and notes to the stated external model service. Prefer not to process third-party or untrusted documents with this skill, and ask the publisher for explicit consent controls, a local-only mode, data minimization, removal or verification of the external fallback import, and clearer limits around medical advice before using it with real patient data.

Vulnerability Patterns
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • 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
Findings (3)

other

Error
Location
scripts/run.py:87
Finding

Sensitive Medication Records Are Transmitted to an External Model Service

Content
View full analysis
str: payload = {"model": MODEL, "temperature": 0.0, "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=120) return json.loads(resp.read().decode("utf-8"))["choices"][0]["message"]["content"] ``` ```python user_prompt = f"""请整理以下用药记录: 总记录数:{len(medications)} 正在服用:{len(active)}种 已停用:{len(stopped)}种 正在服用的药品: ```json {json.dumps(active, ensure_ascii=False, indent=2)} ``` 已停用的药品: ```json {json.dumps(stopped, ensure_ascii=False, indent=2)} ``` 请生成用药管理摘要,分类展示,标注长期/短期用药,给出用药提醒。""" text = _call_llm(SYSTEM_PROMPT, user_prompt, appkey) ``` ### Technical Analysis The application inserts complete medication records into a model prompt and transmits that prompt to `https://maas-api.hivoice.cn/v1/chat/completions`. The transmitted fields can include medication names, doses, frequencies, treatment dates, statuses, and free-form notes. These values constitute sensitive health information, while free-form notes may also contain names, diagnoses, contact information, or other identifying details. The transfer is documented in `SKILL.md`, so it is not covert; however, external inference is mandatory, and the implementation provides no local-only mode, field minimization, pseudonymization, redaction, or technical consent mechanism. The bearer credential is placed in an HTTPS authorization header and is not wri ...[truncated 1140 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Error
Location
scripts/run.py:210
Finding

Fallback Dynamically Executes an Unverified Python Module Outside the Audited Package

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:87
Finding

Untrusted Medication Fields Can Inject Instructions into the Model Prompt

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (21)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared purpose is narrow medication record management, but the documented behavior expands into broad multi-format document ingestion, Office/PDF conversion, and image OCR. That mismatch is dangerous because users and reviewers may grant trust appropriate for a simple record manager while the skill actually processes arbitrary documents and invokes external tooling, expanding attack surface and privacy exposure.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill documents capabilities that imply file access, file writing, shelling out to local tools, environment access, and network transmission, but it does not declare any explicit tool scope or permissions boundaries. In a health-data context, this increases the risk of overbroad execution and makes it harder for a host platform to constrain sensitive operations or review whether the behavior is appropriate.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented medical boundary says the skill does not judge indications or adjust treatment, yet other sections say it produces medical-model analysis and reminders. This contradiction creates a safety and trust problem: users may believe the skill is non-advisory while still receiving clinical-seeming guidance from a model.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill claims to only manage personal medication records, but the output specification includes LLM-generated medical interpretation, analysis, and reminders. In a medical context, that functional drift can mislead users into relying on unvalidated health guidance and also implies transmission of sensitive data beyond basic record storage.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

Requiring external medical-model API inference for a basic medication record management task introduces unnecessary network dependency and sensitive-data exposure. Because medication histories are health data, sending them to a remote endpoint without strong necessity increases confidentiality and compliance risk even if the endpoint is internal.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill states that medication records are sent to an internal medical model API but provides no user-facing warning or consent flow for transmitting sensitive health information. In the healthcare context, undisclosed sharing of medication histories can expose highly sensitive personal data and create substantial privacy, regulatory, and trust risks.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill manifest describes a patient-side long-term medication record management capability, but this module's docstring states it is a 'general file preprocessing tool' for extracting text or tables from PDFs, Office files, JSON, and images. The code throughout the file focuses on content extraction and format conversion rather than medication-list or dose-history management, indicating a semantic mismatch with the declared skill purpose.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module adds external office, PDF, and OCR processing capabilities that are not clearly justified by the medication-record management purpose, substantially increasing attack surface. In this skill context, that mismatch makes the behavior more suspicious and more dangerous because it processes complex untrusted formats through third-party binaries without visible isolation controls.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
77% confidence
Finding

Although the subprocess call avoids shell injection by passing arguments as a list, it invokes a large external document-conversion suite on potentially untrusted office files. Parsing attacker-supplied documents with LibreOffice/soffice meaningfully expands attack surface and can enable denial of service or exploitation of converter vulnerabilities, especially in a server-side preprocessing pipeline.

Content

Scanner excerpt · scripts/preprocess.py (reported line 111)May include surrounding context.

python
if not office_bin:
        raise PreprocessError("libreoffice/soffice not found for office document conversion.")
    with tempfile.TemporaryDirectory(prefix="med-skill-preprocess-") as tmp_dir:
        proc = subprocess.run(
            [office_bin, "--headless", "--convert-to", "txt:Text", "--outdir", tmp_dir, str(path)],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False,
        )

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
78% confidence
Finding

This path uses LibreOffice to convert XLS files supplied by users, which exposes the system to a complex external parser. Even without shell injection, feeding untrusted spreadsheet files to a heavyweight conversion tool can trigger parser bugs, excessive resource consumption, or other unsafe behavior in the host environment.

Content

Scanner excerpt · scripts/preprocess.py (reported line 126)May include surrounding context.

python
if not office_bin:
        raise PreprocessError("libreoffice/soffice not found for xls conversion.")
    with tempfile.TemporaryDirectory(prefix="med-skill-preprocess-") as tmp_dir:
        proc = subprocess.run(
            [office_bin, "--headless",
             "--convert-to", "csv:Text - txt - csv (StarCalc):44,34,76,1",
             "--outdir", tmp_dir, str(path)],

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
72% confidence
Finding

This invokes pdftotext on untrusted PDFs, which introduces risk from external parser vulnerabilities and resource-exhaustion attacks. The subprocess usage itself is not an injection issue, but server-side processing of attacker-controlled PDFs via third-party binaries is a legitimate security concern in a generic ingestion utility.

Content

Scanner excerpt · scripts/preprocess.py (reported line 153)May include surrounding context.

python
pass
    pdf_to_text = shutil_which("pdftotext")
    if pdf_to_text:
        proc = subprocess.run(
            [pdf_to_text, "-layout", str(path), "-"],
            stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False,
        )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code forces Tesseract to use "chi_sim+eng" whenever those language packs are installed, rather than letting the user choose or documenting a justified locale constraint. This is a natural-language locale policy issue because it imposes a language preference automatically for image OCR.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/preprocess.py (reported line 171)May include surrounding context.

python
cmd = [tesseract_bin, str(path), "stdout"]
    if lang_arg:
        cmd.extend(["-l", lang_arg])
    proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False)
    if proc.returncode != 0 or not proc.stdout.strip():
        raise PreprocessError(f"Image OCR failed: {proc.stderr.strip() or 'no text returned'}")
    return proc.stdout

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/preprocess.py (reported line 178)May include surrounding context.

python
def detect_tesseract_langs(tesseract_bin: str) -> Sequence[str]:
    proc = subprocess.run(
        [tesseract_bin, "--list-langs"],
        stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=False,
    )

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The module docstring and the embedded prompts are written to operate in Chinese only, and the system prompt mandates Chinese output formatting and disclaimer text. There is no user opt-in or configurable language choice, which is a language/locale policy concern under the stated rules.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The code sends a patient's full medication records, including drug names, doses, dates, status, and notes, to an external LLM API for processing. In a medical-record-management skill, this is sensitive health data exposure to a third party, and the code contains no consent flow, minimization, anonymization, or disclosure about off-device transfer, making privacy and compliance risk substantial.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Sensitive medication data is transmitted to an external API endpoint, but the code offers no user-facing notice that personal health information leaves the local environment. In healthcare contexts, lack of transparent disclosure and consent materially increases privacy, legal, and trust risks even if transport uses HTTPS.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The system prompt instructs the model to assess drug interaction risks, which is a clinical decision-support function beyond simple record management. Because the output is generated by a general LLM rather than a validated medication-interaction engine, it can produce incomplete or incorrect safety advice that may influence patient behavior in a high-risk medical context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The natural-language system prompt instructs the model entirely in Chinese and requires a fixed Chinese disclaimer at the end. Because no alternative locale or language selection mechanism is provided, the skill enforces a specific language without explicit user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The dependency note specifies Tesseract with chi_sim+eng, which constrains OCR language handling to simplified Chinese and English. The file does not offer users a language choice or explain this as an intentional region-specific limitation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script requires an --appkey credential and uses it to authorize remote API requests, but provides no warning or explanatory comment about how that credential is used. This is relevant because the rule calls for disclosure around access to sensitive credentials when no other user-facing explanation is present.

Content

No source excerpt is available for this finding.