Back to skill

Security audit

MinerU PDF Parser

Security checks for vulnerabilities and agentic risk

Overview

This document-parsing skill is mostly coherent, but its delivery integrations can accidentally read and forward local files referenced by generated Markdown.

Review before installing. Use this only for documents and destinations you trust, avoid confidential or regulated files unless you use an offline path, do not enable remote sinks for untrusted documents, and prefer pinned install commands. Treat parsed Markdown as untrusted until the local image path handling and redirect behavior are fixed.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/sinks/_md.py:40
Finding
Arbitrary Local File Disclosure Through Markdown Image References<![CDATA[ ## Vulnerability Details **File Location**: `scripts/sinks/_md.py:40-56`; exploitation sink at `scripts/sinks/linear.py:33-60` **Vulnerability Type**: Unrestricted local file read and external disclosure **Risk Level**: High ### Vulnerable Code `scripts/sinks/_md.py:40-56`: ```python def find_local_images(markdown: str, base_dir) -> list: """Return ``[(alt, ref, Path)]`` for image refs that point at existing local files.""" base = Path(base_dir) if base_dir else None found = [] seen = set() for match in _IMAGE_RE.finditer(markdown): ref = match.group("ref") if is_remote(ref) or ref in seen: continue path = Path(ref) if not path.is_absolute() and base is not None: path = base / ref if path.is_file(): found.append((match.group("alt"), ref, path)) seen.add(ref) return found ``` `scripts/sinks/linear.py:33-60`: ```python def _data_uri(path: Path) -> str: mime = _MIME.get(path.suffix.lower(), "image/png") b64 = base64.b64encode(path.read_bytes()).decode("ascii") return f"data:{mime};base64,{b64}" @register class LinearSink(Sink): name = "linear" requires = ("LINEAR_API_KEY", "LINEAR_TEAM_ID") label = "Linear issue (GraphQL API)" def deliver(self, doc: ParsedDoc) -> SinkResult: key = self.env("LINEAR_API_KEY") team = self.env("LINEAR_TEAM_ID") headers = {"Authorization": key, "Content-Type": "application/json"} base_dir = Path(doc.markdown_path).parent if doc.markdown_path else None images = _md.find_local_images(doc.markdown, base_dir) mapping = {ref: _data_uri(path) for _alt, ref, path in images} body = _md.rewrite_images(doc.markdown, mapping) status, parsed = _http.request_json("POST", API, headers=headers, payload={ "query": _MUTATION, "variables": {"input": { "teamId": team, "title": doc ...[truncated 2250 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Reject absolute image paths and any path containing parent traversal. 2. Resolve both the output directory and candidate path before reading: ```python base = Path(base_dir).resolve() candidate = (base / ref).resolve() try: candidate.relative_to(base) except ValueError: continue if candidate.is_file(): found.append((alt, ref, candidate)) ``` 3. On supported Python versions, use `candidate.is_relative_to(base)` after canonicalization. 4. Permit only expected generated asset directories, such as `<output>/images/`. 5. Apply an allowlist of supported image extensions and verify file signatures rather than trusting the filename. 6. Reject symbolic links or confirm that their resolved targets remain under the authorized directory. 7. Add file-size limits before reading and Base64-encoding assets. 8. Require explicit confirmation before a sink embeds any local file. 9. Add regression tests for absolute paths, `../` traversal, symlinks, encoded traversal, and paths sharing only a lexical prefix with the allowed directory. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/mineru.py:484
Finding
Authentication Credentials Can Be Forwarded Across Untrusted HTTP Redirects<![CDATA[ ## Vulnerability Details **File Location**: `scripts/mineru.py:484-496`; shared sink transport at `scripts/sinks/_http.py:17-23` **Vulnerability Type**: Cross-origin credential disclosure through unsafe redirect handling **Risk Level**: High ### Vulnerable Code `scripts/mineru.py:484-496`: ```python if status in (301, 302, 303, 307, 308) and _redirects > 0: location = resp.getheader("Location") if location: nxt = urllib.parse.urljoin(url, location) nmethod = "GET" if status in (301, 302, 303) and method != "HEAD" else method ndata = None if nmethod != method else data if ndata is not None and hasattr(ndata, "seek"): try: ndata.seek(0) except OSError: pass return _send_once(nmethod, nxt, headers=headers, data=ndata, timeout=timeout, _redirects=_redirects - 1) ``` `scripts/sinks/_http.py:17-23`: ```python def http_request(method, url, *, headers=None, data=None, timeout=60): """Perform one HTTP request. Returns ``(status_code, body_bytes)``.""" req = urllib.request.Request(url, data=data, method=method, headers=headers or {}) req.add_header("User-Agent", USER_AGENT) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return resp.getcode(), resp.read() ``` ### Technical Analysis The MinerU HTTP client follows redirects by recursively calling `_send_once()` with the original `headers` object. No comparison is made between the original and redirected scheme, hostname, or port. Consequently, an `Authorization` header can be forwarded to a different origin. For status codes 307 and 308, the original request method and body are also retained. This can expose both credentials and uploaded document content to the redirected destination. The shared sink transport delegates redirect behavior to `urllib.request.urlopen()` without establishing an explicit same-origin policy for sens ...[truncated 1574 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse and compare the source and destination origins before following any redirect: ```python old = urllib.parse.urlsplit(url) new = urllib.parse.urlsplit(nxt) same_origin = ( old.scheme.lower(), old.hostname, old.port or (443 if old.scheme == "https" else 80), ) == ( new.scheme.lower(), new.hostname, new.port or (443 if new.scheme == "https" else 80), ) ``` 2. Reject cross-origin redirects for requests containing credentials or sensitive bodies. 3. Never permit an HTTPS-to-HTTP downgrade. 4. If cross-origin redirects are functionally necessary, strip `Authorization`, cookies, API-token headers, and other secrets before following them. 5. Do not replay upload or document bodies to a different origin. 6. Implement a custom `urllib` redirect handler for sink requests that enforces the same policy. 7. Validate configurable service base URLs: - Require HTTPS for non-local integrations. - Reject embedded user information. - Require an expected hostname where self-hosting is not supported. 8. For signed upload URLs, allow only documented object-storage domains or require explicit confirmation before uploading to an unexpected host. 9. Add tests for cross-host, cross-port, scheme-downgrade, protocol-relative, and chained redirects. ]]>

T08 · Insecure Dependencies

Warning
Location
README.md:108
Finding
Documentation Executes an Unpinned Third-Party Package During Installation<![CDATA[ ## Vulnerability Details **File Location**: `README.md:108-119`; equivalent installation guidance in `README_CN.md:82-86` **Vulnerability Type**: Mutable supply-chain dependency execution **Risk Level**: Medium ### Vulnerable Code `README.md:108-119`: ```bash npx skills add Nebutra/MinerU-Skill ``` ```bash npx -y skills add https://smithery.ai/skills/nebutra/mineru-skill ``` ### Technical Analysis The documented installation commands invoke `npx` without pinning the `skills` package to an audited version or integrity digest. `npx` may retrieve and execute the currently published package, meaning the effective installer code can change after this Skill has been reviewed. The `-y` option suppresses installation confirmation, further reducing the opportunity for the user to inspect the resolved package and version. This creates a mutable supply-chain execution path outside the audited repository. The static pre-scan’s README badge findings are not executable downloads by themselves; the relevant risk is the unpinned `npx` execution command. ### Attack Path 1. An attacker compromises the publisher account, package registry entry, dependency tree, or a future release of the `skills` package. 2. The attacker publishes a malicious version under the same package name. 3. A user follows the documented unversioned `npx` command. 4. `npx` resolves the mutable current package version and executes its installation logic. 5. Malicious package code runs with the privileges of the user installing the Skill. ### Impact Assessment A compromised installer package can execute arbitrary code under the installing user’s account. This may permit theft of local credentials, modification of agent configuration, installation of additional malicious components, or tampering with other user-accessible files. The repository itself does not demonstrate that the referenced package is currently malicious. The finding concerns the absence of version and integrity controls ...[truncated 55 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin the installer package to a specific reviewed version: ```bash npx -y skills@<audited-version> add Nebutra/MinerU-Skill ``` 2. Where supported, publish and verify a cryptographic integrity digest or signed provenance for the installer. 3. Avoid suppressing confirmation with `-y` in the primary security-conscious installation instructions. 4. Document the expected package publisher, version, checksum, and registry. 5. Pin repository-based installation to a signed release tag or immutable commit hash rather than an unqualified branch. 6. Recommend downloading and reviewing the installer before execution in high-security environments. 7. Use lockfiles and automated dependency monitoring for any maintained installer or optional dependency workflow. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (86)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
The skill description emphasizes parsing, but environment-driven sink dispatch means parsed data can be forwarded to external destinations when configured. In the context of sensitive PDFs and office files, hidden or under-emphasized forwarding behavior increases the risk of accidental data leakage.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
"""WeCom (企业微信 / WeChat Work) sink — send parsed Markdown as an app message.

WeCom apps deliver content via the message-send API. The native ingestion path
is a ``markdown`` message from a self-built app: first an access token is fetched
with the corp id + secret, then the message is posted. WeCom's markdown is a
limited subset with a 2048-byte content cap and no inline images, so the body is
truncated to fit.
Confidence
70% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Static analysis

No suspicious patterns detected.