T08 · Insecure Dependencies
- Location
scripts/run.py:247- Finding
Untrusted External Python Module Execution During Preprocessing Fallback
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This skill appears purpose-aligned for medical literature analysis, but it should be reviewed because it sends document content to a remote model API and can execute unaudited shared preprocessing code outside the skill package.
Install only if you are comfortable sending the selected literature fields and extracted document text to the maas-api.hivoice.cn medical model service. Avoid using confidential, unpublished, regulated, or licensed content unless your organization has approved that service. Prefer JSON input when possible, avoid passing real appkeys on the command line, and run document/OCR preprocessing in a sandboxed environment if handling untrusted files.
scripts/run.py:247Untrusted External Python Module Execution During Preprocessing Fallback
scripts/run.py:113Prompt Injection Through Untrusted Literature Content
scripts/run.py:234Bearer Token Exposure Through Command-Line Arguments
The skill is presented as a narrowly scoped medical literature-analysis tool, but the markdown specifies broad multi-format document ingestion, OCR, Office/PDF conversion, and generic text extraction via external tools. This mismatch is risky because operators may approve or trust it as a low-risk analysis skill when it actually processes arbitrary files and executes helper binaries, creating a larger and less obvious attack surface.
The skill declares no explicit tool scope or permission boundaries while its documented operation implies use of filesystem access, shell execution, environment-provided secrets, and outbound network access. In an agent platform, this increases the attack surface because users and orchestrators cannot constrain or audit what the skill is allowed to do, especially when it can invoke external binaries and remote APIs.
The description is written as a fixed Chinese-language skill purpose statement, and the document does not indicate that users may choose another language or locale. Under the policy criteria, forcing a specific language without user opt-in is a natural-language policy issue unless the locale restriction is explicitly justified.
The skill clearly states that analysis is performed by an external medical model API and requires an appkey, but it does not provide a prominent privacy warning that uploaded literature contents and extracted text will be transmitted off-platform. In a pharmaceutical R&D context, documents may contain unpublished data, licensed content, or sensitive internal analyses, so silent external transmission can cause serious confidentiality and compliance issues.
The module docstring explicitly describes a '通用文件预处理工具' for extracting text or tables from many file types, including PDFs, Office documents, spreadsheets, JSON, and images. The manifest describes a medical-affairs R&D literature analysis skill, but this code is a generic ingestion/conversion component rather than literature analysis or evidence synthesis behavior.
The top-level natural-language docstring is written as a Chinese-only description and suggests a locale-specific presentation without any indication that language choice is configurable. Under the policy, forcing a specific language without user opt-in can be a locale policy violation unless the constraint is explicitly justified.
The skill invokes multiple local executables (LibreOffice, pdftotext, Tesseract) to process user-provided files, which is broader and riskier than simple literature-text handling. In this skill context, document ingestion is expected, but using several heavyweight external parsers materially increases the attack surface and operational blast radius if hostile files are supplied.
Although this LibreOffice invocation does not use a shell and is not command-injectable, it causes a complex external parser to process attacker-supplied .doc content. Running office conversion on untrusted files increases attack surface substantially because parser vulnerabilities in LibreOffice or related components could lead to denial of service or, in worst cases, code execution in the host environment.
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,
)
This call similarly feeds attacker-controlled .xls data into LibreOffice for conversion. The lack of shell usage prevents classic command injection, but invoking a large external document-processing binary on untrusted spreadsheets introduces parser exploitation and resource-exhaustion risk.
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)],
This pdftotext subprocess uses safe argument passing, but it still hands untrusted PDFs to an external parser. Malicious PDFs can trigger vulnerabilities or extreme resource consumption in PDF tooling, so the security issue is unsafe processing of hostile content rather than 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 system prompt is entirely in Chinese and instructs the model to produce Markdown output with a Chinese disclaimer, while the file provides no opt-in or language selection mechanism. This is a locale/language policy concern because it imposes a specific language on users without documented justification.
The skill sends matched literature content, including titles, abstracts, conclusions, and URLs, to an external API endpoint (maas-api.hivoice.cn) for analysis. In a medical/pharma R&D context, these materials may be proprietary, confidential, or regulated, and the code provides no consent prompt, disclosure, minimization, or configuration to keep processing local, increasing the risk of unintended data exfiltration to a third party.
Accepting the API credential via --appkey exposes the secret to common process-inspection surfaces such as shell history, job logs, CI output, and system process listings. This is especially risky in shared research or enterprise environments, where leaked credentials could let others access the external medical LLM service and any data reachable through that account.
The function runs an external office conversion tool on a user-provided document using subprocess, which is a safety-critical execution path involving file processing outside the Python runtime. The code lacks a user-facing notice, confirmation, or descriptive comment explaining that uploaded documents are handed to LibreOffice/soffice for conversion.
This code calls an external office binary to convert .xls files into CSV, which is a subprocess-based handling of user data. There is no confirmation prompt, user-facing logging, or explanatory comment warning that the spreadsheet will be processed by LibreOffice/soffice.
When native PDF parsing fails, the function falls back to calling pdftotext on the user-provided PDF, which is an external subprocess operation over user content. The code does not include any user-facing warning, confirmation, or explanatory comment about this external processing path.
This function sends the supplied image file to an external OCR executable via subprocess, which is a safety-relevant operation on user data. Although errors are surfaced, there is no confirmation prompt, user-facing log/print, or inline warning/comment disclosing that external processing of the file will occur.