Back to skill

Security audit

unisound-medication-reminder

Security checks for vulnerabilities and agentic risk

Overview

This medication reminder skill is not clearly malicious, but it requires sending sensitive medication details to a remote medical model and supports broad document parsing that deserves review before installation.

Install only if users are comfortable sending medication details and any parsed document contents to the documented remote medical model endpoint. Prefer JSON or simple text inputs from trusted sources, avoid untrusted Office/PDF/image files unless the runtime is isolated, and treat the generated text as reminder formatting rather than medical advice.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (13)

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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,
        )
Confidence
78% confidence
Finding
Although this subprocess call is not shell-injection prone, it feeds untrusted office documents into LibreOffice for conversion. Parsing attacker-controlled DOC files through external document processors expands the attack surface and can enable denial of service or exploitation of vulnerabilities in the external converter, especially in a server or agent environment.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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)],
Confidence
78% confidence
Finding
This call sends untrusted XLS content to LibreOffice for conversion, which is risky because legacy office formats have a long history of parser bugs and resource-exhaustion issues. Even without shell injection, invoking a heavyweight external parser on attacker-controlled files can expose the host process to converter exploits or service disruption.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
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,
        )
Confidence
72% confidence
Finding
Passing untrusted PDFs to pdftotext creates risk through the external PDF parser, which may be vulnerable to malformed-document crashes or exploitation. In this skill's context, generic PDF extraction is not clearly required for medication reminders, so the added parsing surface is harder to justify.

Lp3

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding
The skill advertises broad capabilities including file read/write, shell, network access, and environment use, but does not declare permissions or constrain them in the manifest. In a medical reminder context, this creates unnecessary hidden attack surface: the skill can ingest local files, invoke external tools, and transmit patient data off-device without transparent capability declaration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding
The documented behavior materially exceeds the stated purpose of a simple medication reminder by supporting generic document parsing, OCR, spreadsheet ingestion, and remote model interaction. This mismatch is dangerous because users may provide sensitive medical documents believing the skill only manages reminders, while it actually behaves like a broader data-extraction and transmission pipeline.

Description-Behavior Mismatch

Medium
Confidence
82% confidence
Finding
The skill claims to only manage reminders and not make medication judgments, yet the output contract includes LLM-generated medical interpretation or analysis text. This scope expansion can mislead users into relying on generated medical commentary that is outside the declared boundary and unnecessary for scheduling reminders.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill mandates sending inputs to a remote medical-model API even though reminder generation can be performed locally from structured fields. Requiring remote inference for a reminder-only use case unnecessarily increases exposure of sensitive medication data and creates dependency on an external service for a task that does not need it.

Description-Behavior Mismatch

Medium
Confidence
88% confidence
Finding
The file implements a broad, generic ingestion pipeline for many document and image types that exceeds the stated scope of a medication-reminder skill. This scope expansion increases attack surface and data exposure opportunities without a clear functional need, making the skill more dangerous in context.

Context-Inappropriate Capability

Medium
Confidence
90% confidence
Finding
The skill invokes external office, PDF, and OCR binaries even though such capabilities are not justified by the declared reminder purpose. In context, this materially increases the chance of processing malicious files and abusing local system tooling, which is risky for an agent skill handling potentially sensitive patient-related inputs.

Description-Behavior Mismatch

Medium
Confidence
96% confidence
Finding
The skill sends patient medication details, dosage, schedule, and status to an external LLM API, which is sensitive health information. In a medical adherence context this creates a real confidentiality and compliance risk, especially because the transfer is not minimized, anonymized, or clearly disclosed to the user.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
In the PreprocessError fallback path, the code calls build(data, args.appkey) instead of build(data, target, args.appkey). This argument mismatch can cause runtime failure or incorrect behavior during error handling, making the skill unreliable in a healthcare workflow where missed reminders may affect medication adherence.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The markdown states that medication-related inputs are sent to an internal medical model API but does not present a clear privacy notice, transmission warning, retention statement, or consent step. In a healthcare context, silent transmission of medicine names, schedules, and potentially parsed documents can expose sensitive health information and violate user expectations.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The code transmits medication information to an external API without any visible user-facing warning, consent flow, or privacy notice. Because medication data is health-related and potentially regulated, undisclosed external sharing is particularly dangerous in this patient-facing medical skill.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

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