Back to skill

Security audit

pdf-parser-mineru

Security checks for vulnerabilities and agentic risk

Overview

This PDF parsing skill is mostly purpose-aligned, but it should be reviewed because installation broadly changes Python packages and output handling can read unrelated files from a chosen directory.

Install only in an isolated virtual environment or container, review/pin MinerU dependencies before use, and always choose a fresh empty output directory that does not contain private files. Do not point output_dir at a home, project, or shared directory.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (2)

T08 · Insecure Dependencies

Warning
Location
install.sh:48
Finding

Unpinned Third-Party Packages Create a Supply-Chain Execution Risk

Content
View full analysis

Vulnerability Details

File Location: install.sh:48-61; the same unsafe installation procedure is documented in SKILL.md:121-127 and SKILL_zh.md:121-127
Vulnerability Type: Unpinned and unrestricted third-party dependency installation
Risk Level: Medium

Vulnerable Code

bash
# Update pip
echo "3. Update pip..."
python3 -m pip install --upgrade pip
echo "   pip has been updated"
echo ""

# Install uv
echo "4. Install uv (fast package manager)..."
if ! command -v uv &> /dev/null; then
    pip3 install uv
    echo "   uv installed successfully"
else
    echo "   uv is already installed"
fi
echo ""

# Install MinerU
uv pip install -U "mineru[all]"

The documentation instructs users to execute the equivalent commands:

bash
pip install --upgrade pip
pip install uv
uv pip install -U "mineru[all]"

Technical Analysis

The installer does not pin exact versions of pip, uv, MinerU, or MinerU's transitive dependencies. It also installs the complete mineru[all] optional dependency set and uses the -U upgrade option.

Consequently, the code installed by the script depends on whichever package versions are available from the configured package index at execution time. Package installation can execute package build hooks and other installation-time code. A compromised upstream release, compromised configured index, dependency-confusion condition, or malicious future transitive dependency could therefore result in arbitrary code execution.

Upgrading pip in the active Python environment also modifies shared development tooling beyond the minimum functionality required by this Skill. The absence of a lockfile and integrity hashes prevents users from verifying that reviewed dependency artifacts are the artifacts ultimately installed.

Attack Path

  1. An attacker compromises a dependency release, a transitive dependency, or a package source configured ...[truncated 1187 chars]
Remediation
View remediation

Remediation Suggestions

  1. Pin exact versions of MinerU, uv, and all transitive dependencies in a reviewed lockfile.
  2. Require cryptographic hashes for downloaded artifacts where supported.
  3. Install dependencies from an explicitly configured, trusted package index.
  4. Create and use a dedicated virtual environment instead of modifying the active or system Python environment.
  5. Remove -U from routine installation unless an explicit, reviewed upgrade is intended.
  6. Avoid installing mineru[all]; select only the optional features required by the Skill.
  7. Do not upgrade pip implicitly. Document a tested version range or provision a pinned version inside the isolated environment.
  8. Add dependency scanning and lockfile review to the release process.

T09 · Insecure Skill Coding Practices

Warning
Location
script/pdf_parser.py:152
Finding

Caller-Controlled Output Directory Can Cause Disclosure of Pre-Existing Files

Content
View full analysis

Vulnerability Details

File Location: script/pdf_parser.py:152-163 and script/pdf_parser.py:269-282
Vulnerability Type: Unsafe reuse and recursive scanning of a caller-controlled output directory
Risk Level: Medium

Vulnerable Code

Markdown output handling:

python
# Find generated markdown files
output_files = list(Path(output_dir).rglob("*.md"))
if not output_files:
    return {
        "success": False,
        "error": "No output Markdown file found"
    }

# Read the first markdown file
md_file = output_files[0]
with open(md_file, "r", encoding="utf-8") as f:
    md_content = f.read()

JSON output handling:

python
# Find generated JSON files
output_files = list(Path(output_dir).rglob("*.json"))
if not output_files:
    # If no JSON file exists, attempt to read other files
    all_files = list(Path(output_dir).rglob("*"))
    return {
        "success": False,
        "error": f"No output JSON file found. Files found: {[str(f) for f in all_files]}"
    }

# Read the first JSON file
json_file = output_files[0]
with open(json_file, "r", encoding="utf-8") as f:
    json_content = json.load(f)

Technical Analysis

The output_dir value comes directly from tool arguments. The application creates the directory if necessary but does not require it to be new or empty:

python
os.makedirs(output_dir, exist_ok=True)

After MinerU finishes, the application recursively scans the entire selected directory and chooses the first file matching *.md or *.json. It does not record the files created by the current MinerU invocation, compare directory state before and after execution, or validate that a selected result belongs to the current conversion.

A pre-existing Markdown or valid JSON file beneath the selected directory may therefore be mistaken for generated output and returned through markdown_content or json_content. If no JSON res ...[truncated 1731 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a unique, private per-invocation working directory using tempfile.mkdtemp() or tempfile.TemporaryDirectory().
  2. Apply restrictive permissions, such as mode 0700, to the job directory.
  3. Treat a caller-provided path as a destination only; run MinerU in a fresh internal subdirectory and copy verified results afterward.
  4. Reject non-empty output directories when isolation cannot be provided.
  5. Determine the expected output path from MinerU's contract instead of selecting the first recursively matching file.
  6. If deterministic output naming is unavailable, capture directory state before execution and accept only newly created regular files after execution.
  7. Resolve paths with Path.resolve() and verify that every selected result remains beneath the dedicated job directory.
  8. Reject symlinks and non-regular files before opening results.
  9. Limit traversal depth, file count, and maximum output size.
  10. Do not include an unrestricted recursive directory listing in error messages; return a bounded diagnostic summary instead.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (8)

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · script/pdf_parser.py (reported line 137)May include surrounding context.

python
try:
            # 设置环境变量以强制使用 CPU(避免 MPS 设备限制)
            env = os.environ.copy()
            env["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
            env["MPS_DEVICE"] = "cpu"

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · script/pdf_parser.py (reported line 251)May include surrounding context.

python
try:
            # 设置环境变量以强制使用 CPU(避免 MPS 设备限制)
            env = os.environ.copy()
            env["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
            env["MPS_DEVICE"] = "cpu"

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill documentation exposes shell-based invocation and implies file and environment access, but it does not declare any explicit tool scope such as allowed-tools or permissions. That creates an authorization gap where an agent may run this skill with broader capabilities than intended, including arbitrary local file access via absolute paths and shell execution around the parser workflow.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains user-facing natural-language descriptions and error/help text that assume Chinese as the only language. Under the policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly justified.

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 · script/pdf_parser.py (reported line 142)May include surrounding context.

python
env["MPS_DEVICE"] = "cpu"

            # 执行命令
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,

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 · script/pdf_parser.py (reported line 256)May include surrounding context.

python
env["MPS_DEVICE"] = "cpu"

            # 执行命令
            result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The command-line usage and runtime error strings are presented exclusively in Chinese, which imposes a fixed language on users. The file does not indicate that users can choose another language or that the Chinese-only behavior is an intentional, documented locale limitation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

This is a markdown file, so SQP-2 applies to omissions in user-facing warnings. Line L161 states that nonexistent output directories will be created, which is a filesystem-modifying behavior, but the document presents it as a note rather than an explicit warning about modifying the user's system.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.