Back to skill

Security audit

unisound-medication-reminder

Security checks for vulnerabilities and agentic risk

Overview

This medication reminder skill has review-worthy privacy and execution risks because it sends medication details to a remote model and includes broad document/OCR processing plus an unverified shared-code fallback.

Review carefully before installing. Use it only if you accept sending medication details and an API bearer key to the documented remote model service. Avoid real patient data unless the provider, retention terms, and compliance posture are acceptable. Prefer JSON input over document/OCR input, and do not rely on the generated Markdown as medical advice or dose guidance.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.py:120
Finding

Indirect Prompt Injection Through Untrusted Medication Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/run.py:220
Finding

Bearer API Key Exposed Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/run.py:240
Finding

Unverified Dynamic Execution of Python Code Outside the Skill Package

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (19)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as reminder generation, yet it requires remote API access and bearer-token authentication to send medication-related content to an external medical model service. This undisclosed external dependency changes the trust and data-flow model significantly, creating risk of sensitive data exposure and misuse of provided credentials.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The skill is presented as reminder generation, yet it requires remote API access and bearer-token authentication to send medication-related content to an external medical model service. This undisclosed external dependency changes the trust and data-flow model significantly, creating risk of sensitive data exposure and misuse of provided credentials.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script is a broad document-ingestion and OCR utility handling pdf/doc/docx/xls/xlsx/csv/json/text/images, which does not match a medication-reminder skill's stated purpose. That mismatch materially raises suspicion because unrelated high-complexity parsing capability can be used to exfiltrate, process, or stage sensitive patient documents beyond the minimum required functionality.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill contains subprocess-driven OCR and office/PDF conversion capabilities that are not obviously necessary for reminder workflows, creating an unjustified attack surface. In a healthcare context, this is more dangerous because such ingestion can pull in sensitive patient documents and run external parsers on them, increasing both compromise and privacy risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function packages medication name, dose, reminder times, status, and a three-day schedule into prompts sent to a remote API, but the user-facing CLI and output provide no warning that medical data leaves the local environment. For a patient medication reminder skill, undisclosed exfiltration of health-related data is especially sensitive and can violate user expectations, policy, or regulation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documents capabilities that imply shell, filesystem, environment, and network access, but it declares no explicit tool scope or permission boundaries. In a medical-reminder context, that creates unnecessary ambient authority: the skill could read local files, invoke external binaries, and transmit medication data off-box without clear restriction or user understanding.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill claims it only manages reminders and does not make medical judgments, but its documented output includes medical-model-generated interpretation, analysis, and reminder text. That scope expansion can mislead users into relying on generated medical-style guidance that exceeds the stated safe boundary of simple scheduling.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Mandatory use of a remote medical LLM is not justified for basic reminder scheduling, which can be implemented locally and deterministically. Requiring external inference increases attack surface, introduces unnecessary data exfiltration risk, and creates dependency on credentials and network services for a low-complexity task.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Medication names, doses, schedules, and dates are health-related data, and the documentation states they are sent to a remote medical model API without any prominent privacy warning or consent flow. In the healthcare context, silent transmission of such data is especially sensitive and can violate user expectations, internal policy, or regulatory requirements.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring is written entirely in Chinese and does not indicate any user choice of language or locale. This can violate language/locale policy when the skill is expected to be generally usable without forcing a specific language.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

Although the code avoids shell injection by passing argv as a list, it invokes LibreOffice on attacker-supplied document content. Running complex document converters on untrusted files expands attack surface substantially, and historically such parsers have had memory-corruption and document-triggered exploitation issues.

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
72% confidence
Finding

This launches LibreOffice to convert legacy xls input, again exposing the system to a large external parser on untrusted documents. The main risk is not shell injection but unsafe processing of hostile file formats that may trigger vulnerabilities or cause denial of service.

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
70% confidence
Finding

Invoking pdftotext on untrusted PDFs increases exposure to parser bugs and decompression/resource-exhaustion issues. This is lower risk than shell injection because the command is constructed safely, but it still expands the trusted computing base beyond the medication-reminder skill's needs.

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

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

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The code introduces an external API dependency and requires a separate appkey for a simple medication reminder workflow that is otherwise computed locally. This expands the attack surface, creates opportunities for credential misuse or accidental disclosure, and is not clearly justified by the stated purpose of the skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill sends patient medication details, dosage, schedule, and status to an external LLM API to generate friendly reminder text. In a medical context, this is sensitive health information, and transmitting it off-device/service boundary without explicit consent, disclosure, data handling guarantees, or minimization creates a real privacy and compliance risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The system prompt hardcodes Chinese instructions and patient-facing output style, which effectively constrains the skill to a specific language/locale. There is no opt-in, language selection, or documented justification for limiting output to Chinese only.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill description and all documented output conventions are presented only in Chinese, including the expected skill name and examples, with no indication that users may choose another language or locale. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
scripts/run.py:249