T08 · Insecure Dependencies
- Location
scripts/run.py:180- Finding
Execution of an Unverified Python Module Outside the Audited Package
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill is a postoperative exercise helper, but it can generate patient-facing rehabilitation advice from incomplete inputs, send sensitive medical content to a remote API, and load unaudited shared Python code.
Review this carefully before installing. It should not be used for real patient rehabilitation decisions unless the remote API, medical-data handling, clinical review process, and unaudited shared-code fallback are approved. Users should avoid submitting identifiable medical records or relying on generated exercise frequency, duration, intensity, or precautions as clinician-approved instructions.
scripts/run.py:180Execution of an Unverified Python Module Outside the Audited Package
scripts/run.py:65Prompt Injection Through Untrusted Rehabilitation Document Fields
scripts/run.py:45Generated Medical Exercise Prescriptions Exceed the Documented Safety Boundary
The manifest presents the skill as a narrow rehabilitation guidance display tool, but the documented behavior expands into broad document ingestion, OCR, Office conversion, and text extraction workflows. That mismatch is dangerous because users and reviewers may grant trust or provide sensitive medical files under the assumption of limited functionality, while the actual processing surface is much larger and includes risky parsers and external tools.
This file implements a broad, generic ingestion pipeline for PDFs, Office documents, spreadsheets, JSON, text, and images, which materially exceeds the stated scope of a postoperative exercise-guidance skill. Unnecessary capability expansion increases attack surface, especially because it adds complex parsers and external-tool handling unrelated to the declared medical-guidance purpose.
Patient-related medical fields are assembled into a prompt and sent to an external API without any user-facing warning, consent flow, or disclosure in the code path. In a postoperative rehabilitation setting, even seemingly simple exercise names, phases, and precautions can constitute protected or sensitive health data, making undisclosed transmission particularly risky.
The skill documents capabilities that imply file access, shell execution, environment access, and network egress, but it does not declare any explicit tool scope or permissions boundaries. In a medical-context skill that processes patient-provided inputs, this creates unnecessary ambiguity about what the skill may access and increases the risk of over-privileged execution or accidental misuse of local files, secrets, and external services.
The documentation says the skill must not generate new rehabilitation prescriptions, but the broader parsing and mandatory inference pipeline create pressure toward generalized medical reasoning rather than simple instruction display. In context, that inconsistency can lead to users treating generated output as tailored rehabilitation guidance, especially when the inputs come from heterogeneous clinical documents.
The skill claims to be a guidance-only display mechanism, yet its output contract includes model-generated medical interpretation, analysis, and reminders. In a postoperative rehabilitation setting, this expands the skill from passive rendering into active medical reasoning, which can introduce unsafe or misleading advice beyond the validated source instructions.
The skill accepts PDFs, Office documents, text files, spreadsheets, and images for OCR, but it does not provide a clear warning that these uploads may contain sensitive medical or personally identifiable information. In this medical-use context, broad document ingestion substantially increases the chance of inadvertent exposure of rehabilitation records, discharge instructions, IDs, or other protected data.
A mandatory remote medical LLM API is introduced even though the stated task is simple exercise instruction guidance. This is dangerous because it creates avoidable data exposure, dependency, and prompt-driven behavior risks for sensitive postoperative rehabilitation content, without a clearly necessary functional justification.
The skill requires users to provide an app key and sends content to a remote API, but it does not clearly warn users that their exercise data and potentially sensitive medical information will be transmitted for model inference. In a healthcare context, missing disclosure materially increases privacy and compliance risk because users may unknowingly upload protected health information to a remote service.
OCR and Office/PDF conversion add substantial parser complexity and invoke heavyweight external programs for a skill whose purpose is exercise instruction. In context, these capabilities are hard to justify and increase risk of malicious file-triggered crashes, resource exhaustion, or exploitation of third-party document-processing components.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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 execution is not inherently insecure here, but in the context of a patient exercise instruction skill it is an unnecessary capability that broadens system exposure. Calling external binaries for document conversion creates dependency on host environment integrity and adds avenues for abuse through malicious inputs or compromised PATH-resolved executables.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
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 calls execute external commands. Without careful input validation, this enables command injection.
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 calls execute external commands. Without careful input validation, this enables command injection.
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 calls execute external commands. Without careful input validation, this enables command injection.
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,
)
The skill is presented as postoperative exercise guidance, but it transmits patient exercise/rehabilitation details to an external LLM service to generate the content. In a medical context, those fields can reveal treatment stage, recovery status, and other sensitive health information, creating privacy and compliance risk if users are not explicitly informed and the service is not tightly governed.
The code requires an API key and performs outbound network calls even though the stated purpose is a guidance/view-like exercise instruction capability. This expands the trust boundary and introduces data exfiltration, dependency, and supply-chain risk that is not obviously necessary for the described functionality.
The system prompt is written entirely in Chinese and instructs the model to produce Markdown output accordingly, with no mechanism for user language selection or opt-in. This imposes a specific language/locale behavior that may violate language-choice policy when the skill is used in broader contexts.
Untrusted input fields are interpolated directly into the LLM prompt with no delimiting, validation, or instruction-neutralization. An attacker controlling exercise_name, instruction, or precautions could inject adversarial natural-language instructions that cause the model to ignore medical constraints, produce unsafe guidance, or emit manipulated content in a patient-facing medical workflow.
The top-level docstring is written only in Chinese and presents the tool description in a fixed language, with no indication that language choice is configurable or intentionally region-specific. Under the policy rules, natural-language content that imposes a specific language without opt-in can be a locale/language policy violation.