What's the vulnerability?

User control of the first argument of the loadFile method in the node.js build allows local file inclusion/path traversal.

If given the possibility to pass unsanitized paths to the loadFile method, a user can retrieve file contents of arbitrary files in the local file system the node process is running in. The file contents are included verbatim in the generated PDFs.

Other affected methods are: addImage, html, addFont.

Only the node.js builds of the library are affected, namely the dist/jspdf.node.js and dist/jspdf.node.min.js files.

Root Cause Analysis

# Root Cause Analysis - GHSA-f8cm-6447-x5h2 (jsPDF Local File Inclusion / Path Traversal)

Summary
- Vulnerability: Local File Inclusion/Path Traversal via file-loading helpers in jsPDF Node builds
- Impact: Attacker-controlled path arguments to jsPDF APIs can read arbitrary files on the server and embed their raw bytes into generated PDFs
- Affected: jsPDF <= 3.0.4 (Node builds: dist/jspdf.node.js and dist/jspdf.node.min.js)
- Fixed: jsPDF >= 4.0.0 (default deny FS reads; requires explicit enable or Node --permission)

Reproduction Evidence
- Vulnerable version 3.0.4: Passing a local path to doc.addImage(secret.txt, ...) produced a PDF containing the secret token from a local file
  - See logs: logs/run_*.log -> shows [HIT] for vulnerable:addImage
  - Artifact: repro_work/vuln/out_addImage.pdf contains the token string (search via `grep -a`)
- Patched version 4.0.0 (latest at test time): Same PoC raises an error and does not create a PDF
  - Error: "Trying to read a file from local file system... set jsPDF.allowFsRead or use --permission --allow-fs-read"
  - No token present in patched outputs; bypass suite attempts did not exfiltrate

Root Cause Details
- In Node builds <=3.0.4, helper function loadFile() directly accepted user-provided paths and read files without restriction. Several high-level APIs (addImage, html, addFont) used this helper when passed a string path (as opposed to binary data), causing raw file contents to be embedded in the PDF stream.
- The 4.0.0 patch introduces permission gating for file system access with jsPDF.allowFsRead defaulting to false and honoring Node.js permission model flags. Calls trying to resolve string paths emit a hard error unless enabled.

Exploitation Path
1. Import jsPDF Node build (require('jspdf/dist/jspdf.node.js'))
2. Provide attacker-controlled relative or absolute path to doc.addImage (or html/addFont)
3. Vulnerable loader reads the file and embeds content verbatim into the PDF
4. Attacker obtains the PDF and extracts embedded sensitive content

Patched Behavior Verification
- Tested latest npm release (4.0.0) which is newer than the first patched tag or equal; verified it blocks file reads by default
- Error message confirms new permission gate; no PDFs contained secret token

Mitigations/Recommendations
- Upgrade to jsPDF >= 4.0.0
- In production Node 22+/23+/24+, use --permission with --allow-fs-read narrowly scoped if jsPDF needs local asset reads
- For older Node versions, sanitize and whitelist any paths passed to jsPDF APIs; avoid passing user-provided paths directly

Artifacts
- logs/run_*.log: Full run logs including errors and hits/misses
- logs/summary.log: Reproduction summary (FOUND/MISSING etc.)
- repro_work/vuln/out_addImage.pdf: Vulnerable PoC artifact containing secret token
- repro_work/patched/*: Patched tests and bypass attempts outputs
One Command

Verify with pruva-verify

Run the Pruva CLI to automatically fetch and execute the reproduction script.

pruva-verify REPRO-2026-00044
or pruva-verify GHSA-f8cm-6447-x5h2
or pruva-verify CVE-2025-68428
Install: curl -fsSL https://pruva.dev/install.sh | sh

Or Run Manually

1

Download the script

curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00044/artifacts/reproduction_steps.sh
2

Make executable

chmod +x reproduction_steps.sh
3

Run the script

./reproduction_steps.sh
Run in a VM, container, or disposable environment. This exploits a real vulnerability.

How Pruva Reproduced This

Watch the AI agent's step-by-step process.

Loading session...

Artifacts

No artifacts available