Back to skill

Security audit

MiniMax PDF

Security checks for vulnerabilities and agentic risk

Overview

This PDF skill mostly does what it claims, but it can automatically install unpinned software and render PDFs with unrestricted remote or local resources.

Review before installing. Use only in an isolated environment with trusted input files, preinstall pinned dependencies yourself, avoid running the auto-fix path, and do not allow untrusted cover metadata, remote image URLs, or file:// image paths.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/cover.py:986
Finding

Unescaped Cover Metadata Enables HTML Injection and Unrestricted Resource Loading

Content
View full analysis
{t["subtitle"]}' image_block = "" if img_url: image_block = f"""
""" abstract_block = "" if t.get("abstract"): abstract_block = f"""
Abstract: {t['abstract']}
""" ``` The generated HTML is subsequently opened in a browser without request filtering: ```javascript const page = await browser.newPage(); const fileUrl = "file://" + path.resolve(inputFile); await page.goto(fileUrl); await page.waitForTimeout(waitMs); ``` Google Fonts are also loaded directly from token data at `scripts/cover.py:19-23`: ```python def _gfonts_import(t: dict) -> str: """Return a CSS @import for the document's Google Fonts, if available.""" url = t.get("gfonts_import", "") if url: return f"@import url('{url}');" return "" ``` ### Technical Analysis Cover metadata is inserted directly into HTML and CSS without contextual escaping. In particular: - `cover_image` is placed inside a double-quoted HTML attribute. - `abstract`, `subtitle`, `title`, and other metadata are inserted as raw HTML text. - Font URLs and design tokens are inserted into CSS without validation. - Playwright opens the result as a local `file:// ...[truncated 2588 chars]
Remediation
View remediation
{ const url = new URL(route.request().url()); if (url.protocol === "file:" && path.resolve(url.pathname).startsWith(approvedRenderDirectory)) { return route.continue(); } return route.abort(); }); ``` If external resources are necessary, add narrowly scoped exceptions after validating the destination. 5. Render with JavaScript disabled unless a cover template demonstrably requires it: ```javascript const context = await browser.newContext({ javaScriptEnabled: false }); const page = await context.newPage(); ``` 6. Replace live Google Fonts with locally bundled, reviewed font files. This makes rendering deterministic and avoids unnecessary network disclosure. 7. Validate CSS token formats: - Colors should match a strict hexadecimal-color expression. - Font names should come from an internal allowlist. - Reject control c ...[truncated 259 chars]

T08 · Insecure Dependencies

Error
Location
scripts/render_body.py:37
Finding

Normal Document Processing Automatically Installs Unpinned Dependencies

Content
View full analysis
/dev/null \ || python3 -m pip install ...[truncated 3230 chars]
Remediation
View remediation
--hash=sha256: pypdf== --hash=sha256: matplotlib== --hash=sha256: ``` Install with hash enforcement: ```bash python -m pip install --require-hashes -r requirements.txt ``` 5. Use a project-local Node installation with a committed lockfile instead of `npm install -g`. Install with a lockfile-enforcing command such as `npm ci`. 6. Pin and provision the Playwright browser during a controlled build or installation stage. Do not download Chromium automatically during cover rendering. 7. Remove `shell: true` from `spawnSync`: ```javascript spawnSync("npx", ["playwright", "install", "chromium"], { stdio: "inherit", shell: false }); ``` 8. Prefer a prebuilt, versioned container or reproducible environment containing all reviewed dependencies. 9. Generate and review a software bill of materials, monitor dependency advisories, and update locked versions through a controlled review process. 10. Run PDF processing under a dedicated low-privilege account with restricted filesystem and network access so that a future dependency compromise has limited impact. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (50)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The supplied code is narrowly focused on rendering cover.html from design tokens. It selects among predefined cover patterns and writes HTML/CSS, including optional Google Fonts imports and optional image references. While this relates to document visual design identity, it only implements cover-page HTML generation, not the broader declared skill behaviors: creating full PDFs, filling form fields in existing PDFs, inspecting PDF fields, or reformatting documents into polished PDFs. The primary purpose in the code is materially narrower than the declared purpose, so this is a mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The code’s actual function is narrowly limited to inspecting fillable fields in an existing PDF. This aligns only with the small part of the description about identifying what fields a PDF has. However, the declared purpose emphasizes a much broader and different primary purpose: visually polished PDF generation, document design identity, token-based styling, reformatting, and form filling. None of those core capabilities are implemented in this code chunk. The script only reads PDF structure and reports metadata about form fields; it never modifies the PDF or produces a styled output. Therefore the description materially overstates and misrepresents what this code actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code only implements the 'fill form fields' portion of the declared description. It reads an existing PDF with AcroForm fields, writes provided values into those fields, validates some field types, and saves the result. It does not generate PDFs from scratch, reformat existing documents, apply a design system, or provide any appearance/branding/layout functionality described as the skill's primary value proposition. Because the declared purpose emphasizes visual quality, design identity, and multiple create/reformat capabilities, while the actual code is a narrow form-filling tool, this is a material description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a visually oriented PDF generation and styling skill: creating professional PDFs, filling form fields, and reformatting content using a design system. The supplied code does none of that. It simply takes two already-existing PDFs, appends their pages together, optionally writes title metadata, and emits a QA summary. This is a materially different primary purpose from the declared one. While dependency installation is a supporting detail, the core mismatch is that the code is a narrow merge utility, not a document creation, form-filling, or design-formatting skill.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code chunk does implement part of the declared design-system concept: it infers visual tokens based on document type and metadata. However, it does not itself create PDFs, fill forms, inspect fields, or reformat existing documents. Its primary behavior is much narrower—token generation for downstream scripts. Therefore the declared description materially overstates the capabilities of this code chunk relative to what it actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code aligns with part of the declared description: it does generate aesthetically styled, print-oriented PDFs using design tokens and consistent visual styling. However, the declared purpose also claims FILL capabilities (complete PDF form fields, inspect fields) and REFORMAT capabilities (apply style to an existing doc/PDF, convert Markdown/text to PDF). This code does none of those things. It accepts structured content.json plus tokens.json and renders a new PDF body from predefined block types. There is no parsing of existing PDFs, no AcroForm/form-field handling, no PDF field enumeration, no ingestion of Markdown/plain text for conversion, and no restyling of an existing document. The imported pypdf dependency is not actually used for such operations in this chunk. Therefore the description materially overstates the skill’s capabilities relative to the supplied code.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared description promises a comprehensive PDF skill for creating, filling, and reformatting documents with consistent design tokens and print-ready output. This code chunk only accepts an input HTML file and outputs a PDF by loading the local file in Playwright and calling page.pdf(). It does not inspect or fill PDF form fields, parse Markdown/text, apply a design system, generate content from scratch, or restyle existing PDFs/documents. While rendering HTML to PDF is loosely related to PDF creation and visual output, the implemented behavior is materially narrower than the declared primary purpose and misses several core advertised capabilities.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The documentation permits cover_image loading from absolute URLs and file:// paths without warning about external retrieval or local file access. This is dangerous because it can turn a styling feature into a mechanism for reading local files or causing outbound requests to attacker-controlled destinations, with results potentially embedded into the output PDF. Given the skill's purpose, this capability is far more powerful than necessary and increases abuse potential substantially.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

A PDF rendering skill should not need to alter the Python environment during execution, yet this code installs packages on demand using pip with --break-system-packages. That expands the trust boundary from local rendering to remote code acquisition and environment mutation, making the skill materially more dangerous than its stated purpose suggests.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

On launch failure, the script spawns 'npx playwright install chromium' through a shell at runtime, causing code and binaries to be fetched and installed during document rendering. For a PDF-rendering skill, this exceeds expected behavior and creates a significant supply-chain and environment-modification risk, especially if run in privileged CI, agent, or workstation contexts.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README's fix path tells users to auto-install missing dependencies, including system/global tooling, which goes beyond ordinary document generation and can modify the host environment. For a PDF skill, automatic environment mutation increases risk because it may install packages, browsers, or runtimes with elevated trust and little user scrutiny.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The README advertises an auto-install command without clearly warning that it changes the local environment, potentially installing global packages and browser dependencies. Users may interpret fix as a harmless validation step rather than an environment-modifying action, increasing the chance of uninformed execution.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

The README instructs users to run npx playwright without pinning a specific version, which allows whatever version is current at execution time to be fetched and run. In a skill context, this creates supply-chain risk and undermines reproducibility, especially because the command installs and executes external tooling during setup.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Loading cover fonts from Google Fonts at render time means document generation triggers outbound network access to third-party infrastructure. In the context of a PDF-generation skill, this expands the trust boundary, leaks metadata about usage, and can introduce integrity and availability risks that are not necessary for many local rendering workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README notes that fonts load at render time but does not clearly warn that rendering will make network requests to third parties. In a local document-processing skill, undisclosed network behavior is security-relevant because it can expose document-generation activity and create policy or privacy violations in restricted environments.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
83% confidence
Finding

This repeated npx playwright usage again relies on an unpinned package version, exposing users to unexpected or compromised upstream releases at install time. Because the README presents it as normal setup for the skill, users may execute it without understanding that remote code is being selected dynamically.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This repeated setup guidance again presents fix as a convenience command without prominently disclosing that it will alter the system environment. Repetition of unsafe setup UX increases the chance that users run modification commands casually, especially in an agent-skill ecosystem where quick-start instructions are often followed verbatim.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill instructs the agent to use shell commands, install dependencies, inspect environment state, and write output files, but it does not declare any explicit tool scope or permissions boundaries. That increases the chance the skill is invoked with broader privileges than necessary, making misuse or accidental execution of local commands and file writes more likely.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The trigger phrases are very broad, including common requests like 'make a PDF' or 'generate a report,' which can cause over-invocation of a high-capability skill. In an agent setting, broad routing increases the risk that shell execution, file writes, document conversion, or dependency-install paths are activated for ordinary requests without clear user intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The FILL workflow writes values into an existing PDF-derived output, but the documentation does not prominently warn that user-supplied data will be inserted into a document file. In practice this can lead to accidental modification of sensitive forms, incorrect handling of confidential data, or user surprise about persistent file changes.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
92% confidence
Finding

The installation instruction uses npx playwright without pinning a specific version, which can fetch different code over time and makes builds non-reproducible. In an agent or automation environment, this creates a supply-chain risk because an unexpected upstream release or compromise could execute unreviewed code during installation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The design documentation explicitly states that cover fonts are loaded live via @import during Playwright rendering. That introduces outbound network access during document generation, which expands the skill's capabilities beyond local PDF formatting and can leak request metadata or enable dependency on untrusted remote content. In a PDF-generation skill, this is more dangerous because rendering user-controlled content should not require hidden external fetches.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The markdown describes live remote font fetching without warning users that PDF rendering may contact external services. Lack of disclosure weakens informed consent and makes it easier for users to unknowingly expose document metadata, request timing, or environment details during generation. In a design-focused skill, hidden network access is not reasonably expected from the manifest alone.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
99% confidence
Finding

Allowing cover_image to reference absolute URLs or file:// paths lets rendering fetch remote resources or read local files during PDF generation. If user input can influence this token, the skill could be abused for SSRF-style outbound requests or local file disclosure by embedding sensitive local content into the produced PDF. In this skill context, that is especially risky because image retrieval is ancillary to styling, not essential to core PDF generation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script embeds unvalidated external URLs from token data into generated HTML via Google Fonts @import and image src attributes. When that HTML is later rendered to produce a PDF, the renderer may make outbound network requests, causing privacy leaks, non-deterministic builds, tracking exposure, and possible abuse of internal network access depending on the rendering environment.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/make.sh:79

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/render_cover.js:41