Back to skill

Security audit

md-pdf-render

Security checks for vulnerabilities and agentic risk

Overview

This Markdown-to-PDF skill appears purpose-aligned, but it needs review because it renders raw HTML in a network-enabled browser and can load mutable third-party Mermaid code from a CDN.

Install only if you are comfortable running an npm/Puppeteer tool and converting trusted Markdown. Do not use it on untrusted documents or sensitive private notes unless you first disable raw HTML/JavaScript and block network access during rendering. Mermaid mode is the highest-risk option because it loads third-party code from a CDN at conversion time; prefer a locally bundled, pinned Mermaid dependency and strict security settings.

Vulnerability Patterns
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • 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
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/md-pdf-render.mjs:79
Finding

Untrusted Markdown Can Execute Active Content with Unrestricted Network Access

Content
View full analysis
${hljsCss} ${katexCss} ${baseCSS} ${extraCss} ${mermaidStyles} ${htmlBody} ${mermaidScript} `; ``` ```js const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.setContent(fullHtml, { waitUntil: 'load', timeout }); ``` ### Technical Analysis The Markdown parser explicitly enables raw HTML through `html: true`. The resulting HTML is inserted directly into a Puppeteer page without sanitization. Chromium JavaScript execution remains enabled, and the renderer does not configure request interception, a Content Security Policy, or a network allowlist. Consequently, an attacker-controlled Markdown document can contain executable HTML such as `
Remediation
View remediation
{ const url = new URL(request.url()); if (url.protocol === 'data:' || url.protocol === 'about:') { request.continue(); } else { request.abort(); } }); ``` 5. If remote resources are a required feature, make them an explicit opt-in and enforce: - HTTPS-only requests. - A documented hostname allowlist. - Blocking of loopback, link-local, private, and metadata-service addresses. - Redirect revalidation. - Response-size and timeout limits. 6. Add a restrictive Content Security Policy to the generated page. 7. Clearly document that untrusted Markdown must not be rendered with active HTML or remote-resource access enabled. ]]>

T03 · Remote Payload Retrieval and Execution

Error
Location
scripts/md-pdf-render.mjs:360
Finding

Mermaid Mode Retrieves and Executes Mutable Remote JavaScript

Content
View full analysis
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs'; mermaid.initialize({ startOnLoad: false, theme: '${theme === 'vscode' ? 'dark' : 'default'}', securityLevel: 'loose', fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif' }); ``` The generated script is inserted into the page and executed by Puppeteer: ```js ${htmlBody} ${mermaidScript} `; const browser = await puppeteer.launch({ headless: true }); const page = await browser.newPage(); await page.setContent(fullHtml, { waitUntil: 'load', timeout }); ``` ### Technical Analysis When `--mermaid` is enabled, the renderer imports executable JavaScript from jsDelivr at runtime. The URL uses the floating major-version selector `mermaid@11`, so the effective code can change after this Skill has been reviewed. The downloaded module is not protected by a local integrity check or a fixed artifact hash. Trust is therefore placed in the CDN, DNS resolution, the upstream package publisher, and every future Mermaid 11 release selected by the CDN. The project already declares Mermaid as a local dependency, making the remote runtime import unnecessary for the declared PDF-rendering functionality. The configuration also selects `securityLevel: 'loose'`, which weakens Mermaid's restrictions when processing diagram definitions. ### Attack Path 1. A user invokes the converter with the `--mermaid` option. 2. The generated HTML contains an import from `cdn.jsdelivr.net`. 3. Chromium connects to the CDN during rendering. 4. The CDN supplies whichever artifact currently resolves for `mermaid@11`. 5. The remotely su ...[truncated 810 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/package-lock.json:2073
Finding

Dependency Installation Uses a Non-Default Registry Mirror and Executes Puppeteer Installation Code

Content
View full analysis
/scripts && npm install ``` ### Technical Analysis The lockfile directs package downloads to `registry.npmmirror.com` rather than the default npm registry. Although SHA-512 integrity values materially reduce undetected artifact modification, the installation still relies on the mirror serving the artifact represented by the lockfile and expands the project's supply-chain trust boundary. Puppeteer has an installation lifecycle script. Such scripts execute with the permissions of the user running npm and may perform network downloads, including downloading a Chromium binary. This behavior is expected for Puppeteer but is broader than a purely local dependency extra ...[truncated 1553 chars]
Remediation
View remediation
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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (23)

Known Vulnerable Dependency: extract-zip==2.0.1 — 2 advisory(ies): CVE-2026-19693 (extract-zip allows arbitrary file writes through symlink archive entries); CVE-2026-56876 (extract-zip unvalidated symlink path traversal)

High
Category
Supply Chain
Confidence
96% confidence
Finding

extract-zip 2.0.1 has reported arbitrary file write and symlink traversal issues during archive extraction. This package is pulled in through Puppeteer's browser management stack, and if an attacker can influence downloaded browser archives, cache contents, or installation inputs, it could lead to filesystem overwrite during install or browser fetch operations.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: ip-address==10.2.0 — 3 advisory(ies): CVE-2026-54272 (ip-address: misclassification of IPv4-mapped/NAT64 IPv6 addresses can bypass SSR); CVE-2026-69198 (ip-address: a CIDR suffix on the parsed address suppresses special-use classific); CVE-2026-69192 (ip-address: Address4 decodes leading-zero octets as decimal while resolvers deco)

High
Category
Supply Chain
Confidence
81% confidence
Finding

ip-address 10.2.0 is associated with address-classification weaknesses that can undermine SSRF protections relying on special-use IP detection. In this lockfile it appears under proxy-related dependencies, so the issue is only directly exploitable if the application uses this library or its consumers for network-allow/deny decisions around untrusted URLs.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: js-yaml==4.1.1 — 4 advisory(ies): CVE-2026-84375 (js-yaml: maxTotalMergeKeys does not limit CPU use for empty merge sources); CVE-2026-59869 (js-yaml: YAML merge-key chains can force quadratic CPU consumption); GHSA-5p4m-2wfm-xmqj (JS-YAML: Quadratic CPU consumption in !!omap resolution (3.x and 4.x) — CVE-2026) +1 more

High
Category
Supply Chain
Confidence
94% confidence
Finding

js-yaml 4.1.1 has multiple algorithmic complexity and CPU exhaustion advisories. Because Puppeteer depends on cosmiconfig, an attacker who can supply crafted YAML configuration files in the execution environment could trigger denial of service during config parsing, though this is not the primary data path of Markdown-to-PDF rendering.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: linkify-it==5.0.1 — 1 advisory(ies): CVE-2026-59887 (linkify-it: Quadratic-complexity DoS via the `mailto:` validator scan-loop on at)

High
Category
Supply Chain
Confidence
95% confidence
Finding

linkify-it 5.0.1 is vulnerable to quadratic-time processing on crafted mailto-like input. Since markdown-it uses linkify-it and this skill processes attacker-controlled Markdown, a malicious document can cause excessive CPU use during parsing, making this especially relevant to the skill's core functionality.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

The skill documentation is written entirely in Chinese, and there is no indication that users may choose another language or that the locale restriction is intentional and justified. This can violate a language/locale policy when users are not given opt-in or an alternative.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This skill drives Markdown through a browser rendering pipeline via Puppeteer/Chromium, and the documentation explicitly discusses images and custom CSS without warning that rendering can fetch remote resources or access local file paths referenced by the Markdown/HTML. That can leak network metadata, unintentionally expose local file contents or paths to the renderer, and create privacy or policy violations when users convert untrusted documents.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill performs remote code fetching for Mermaid rendering without clear user-facing disclosure, so users may unknowingly cause network egress and third-party code execution simply by enabling a rendering feature. This is especially risky in CI, offline-sensitive, or high-trust document-processing environments where hidden external dependencies violate expected behavior and security assumptions.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

When Mermaid is enabled, the renderer injects a module import from a public CDN into a headless browser context, causing unpinned remote JavaScript to be fetched and executed during document conversion. In a conversion tool that processes user-controlled Markdown, this expands the trusted computing base to third-party network content and creates supply-chain and unexpected network-execution risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Mermaid is initialized with securityLevel: 'loose', which weakens built-in restrictions in a context that renders attacker-controlled diagram definitions from Markdown. For a document conversion utility, permissive rendering increases the chance that diagram content can trigger unsafe HTML/URL handling or browser-side script-adjacent behavior during PDF generation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The natural-language content of the skill, including the manifest description and all usage instructions, is presented only in Chinese. This can violate a language/locale policy when no user opt-in, alternative language, or justified region-specific constraint is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file's natural-language description, help text, errors, and status messages are written in Chinese only. This imposes a specific language on users without any opt-in or documented locale justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: dompurify==3.4.8 — 4 advisory(ies): CVE-2026-75838 (DOMPurify: IN_PLACE hook removal leaves a detached subtree executable, causing X); CVE-2026-66010 (DOMPurify: `CUSTOM_ELEMENT_HANDLING` bypasses `afterSanitizeElements` for allowe); CVE-2026-65898 (DOMPurify: Permanent `ALLOWED_ATTR` pollution via `setConfig()` bypassing the ho) +1 more

Low
Category
Supply Chain
Confidence
92% confidence
Finding

dompurify 3.4.8 is flagged with multiple sanitizer-bypass issues. In this skill, Mermaid is present and may render untrusted diagram/HTML-like content before PDF generation, so a sanitizer bypass could permit script or active markup to survive into the headless browser rendering step, increasing risk beyond a purely client-side display bug.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: mermaid==11.15.0 — 5 advisory(ies): CVE-2026-71436 (Mermaid XY Charts are vulnerable to an infinite loop DoS); CVE-2026-71437 (Mermaid Architecture diagrams are vulnerable to prototype pollution); CVE-2026-50159 (Mermaid allows CSS injection applying to sibling elements of the diagram) +2 more

Low
Category
Supply Chain
Confidence
95% confidence
Finding

mermaid 11.15.0 has multiple reported issues including infinite-loop DoS, prototype pollution, and CSS injection. This is highly relevant because the skill explicitly supports Mermaid rendering from Markdown, so untrusted diagram blocks could directly trigger parser hangs or alter rendered output during PDF generation in Puppeteer.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 6)May include surrounding context.

json
"version": "1.1.0",
  "type": "module",
  "dependencies": {
    "highlight.js": "^11.9.0",
    "katex": "^0.17.0",
    "markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 7)May include surrounding context.

json
"type": "module",
  "dependencies": {
    "highlight.js": "^11.9.0",
    "katex": "^0.17.0",
    "markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 8)May include surrounding context.

json
"dependencies": {
    "highlight.js": "^11.9.0",
    "katex": "^0.17.0",
    "markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 9)May include surrounding context.

json
"highlight.js": "^11.9.0",
    "katex": "^0.17.0",
    "markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 10)May include surrounding context.

json
"katex": "^0.17.0",
    "markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",
    "mermaid": "^11.0.0",

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 11)May include surrounding context.

json
"markdown-it": "^14.0.0",
    "markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",
    "mermaid": "^11.0.0",
    "puppeteer": "^22.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 12)May include surrounding context.

json
"markdown-it-anchor": "^9.0.0",
    "markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",
    "mermaid": "^11.0.0",
    "puppeteer": "^22.0.0"
  }

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 13)May include surrounding context.

json
"markdown-it-emoji": "^3.0.0",
    "markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",
    "mermaid": "^11.0.0",
    "puppeteer": "^22.0.0"
  }
}

Known Vulnerable Dependency: mermaid==11.15.0 — 5 advisory(ies): CVE-2026-71436 (Mermaid XY Charts are vulnerable to an infinite loop DoS); CVE-2026-71437 (Mermaid Architecture diagrams are vulnerable to prototype pollution); CVE-2026-50159 (Mermaid allows CSS injection applying to sibling elements of the diagram) +2 more

Low
Category
Supply Chain
Confidence
98% confidence
Finding

The manifest permits installation of mermaid 11.15.0, which is reported as having multiple known security issues including denial of service, prototype pollution, and CSS injection. In a Markdown-to-PDF renderer that may process untrusted Markdown/diagram content, a vulnerable diagram engine is more dangerous because attacker-supplied Mermaid blocks could trigger browser-side or rendering-time compromise effects during conversion.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · scripts/package.json (reported line 14)May include surrounding context.

json
"markdown-it-task-lists": "^2.1.1",
    "markdown-it-texmath": "^1.0.0",
    "mermaid": "^11.0.0",
    "puppeteer": "^22.0.0"
  }
}

Static analysis

No suspicious patterns detected.