TLDR;
A critical local file inclusion and path traversal vulnerability has been disclosed in jsPDF, a widely-adopted npm package for generating PDF documents in JavaScript applications. The flaw, tracked as CVE-2025-68428 and GHSA-f8cm-6447-x5h2, allows attackers to read arbitrary files from the local filesystem and exfiltrate their contents by embedding them within generated PDFs.
Successful exploitation results in unauthorized disclosure of sensitive data including configuration files, environment variables, credentials, and other files accessible to the Node.js process. File contents are included verbatim in generated PDFs, enabling data exfiltration through normal application output. As a result, this is considered a critical vulnerability with a CVSS v4.0 score of 9.2.
Affected versions
- The vulnerability affects only the Node.js builds of jsPDF (dist/jspdf.node.js and dist/jspdf.node.min.js). Browser builds are not affected. Organizations running jsPDF in server-side environments where user input reaches vulnerable methods should treat this as a high-priority remediation item.
- The fix in jsPDF 4.0.0 prevents the vulnerability by default by requiring Node.js to run in permission mode. However, upgrading and configuring it correctly can be challenging in practice. Many environments run older Node.js versions that lack stable permission mode support, and enabling --permission may break existing functionality if filesystem access patterns haven't been carefully mapped.
- Additionally, there are numerous conditions under which this vulnerability is not exploitable. The central question is whether an attacker or user can control the first argument passed to the affected methods (loadFile, addImage, html, addFont). If file paths are hardcoded or derived from trusted sources, the risk is significantly reduced. We've written this advisory to help teams make informed decisions about prioritization and remediation approaches based on their specific exposure.
What happened
- Security researcher Kwangwoon Kim (kilkat) identified the vulnerability and reported it through GitHub's security advisory process. The advisory (GHSA-f8cm-6447-x5h2) was published on January 3, 2026.
- The jsPDF maintainers addressed the issue in version 4.0.0 by restricting filesystem access by default.
Technical analysis
The vulnerability originates in the loadFile method within jsPDF's Node.js builds. When user-controlled input is passed as a file path argument, the library reads the specified file from disk and incorporates its contents verbatim into the generated PDF output.
Several public-facing methods are affected:
addImagehtmladdFont
Each of these methods internally calls loadFile, meaning any unsanitized path passed to them becomes an attack vector.
Exploitation Example
import { jsPDF } from "./dist/jspdf.node.js";
const doc = new jsPDF();
doc.addImage("./secret.txt", "JPEG", 0, 0, 10, 10);
doc.save("test.pdf");
// The generated PDF will contain the "secret.txt" file contentsThe file type parameter (e.g., "JPEG") does not prevent non-image files from being read. The library reads whatever file path is provided and embeds the raw content. Path traversal sequences allow reading files outside the intended directory scope. This becomes externally exploitable when a user controlled value is passed to the first parameter within the impacted methods.
Mitigation
Assess Exploitability
Use the following steps to verify exploitability:
1. SCA with reachability: SCA tools with reachability may identify affected code paths for your organization. If none of the affected methods are reachable, then the vulnerability is not exploitable.
2. Server-side usage: Verify whether jsPDF is used server-side. If the library is used exclusively on the client side, this vulnerability does not apply.
3. Existing permissions: Check if you are already running Node.js with permission mode and have properly scoped filesystem permissions.
4. Search your codebase for usage of the vulnerable methods: If SCA with reachability is not an option, you can manually search using grep:
grep -rE "\.(addImage|addFont|html|loadFile)\s*\(" --include="*.js" --include="*.ts" ./srcFor each match, trace the first argument to determine its origin:
Not exploitable — The path is hardcoded or derived from trusted configuration:
// Static path - not exploitable
doc.addImage("./assets/logo.png", "PNG", 10, 10, 50, 50);Potentially exploitable — The path incorporates user input, request parameters, database values, or external data:
// User input directly used
app.post("/generate-pdf", (req, res) => {
const doc = new jsPDF();
doc.addImage(req.body.imagePath, "PNG", 10, 10, 50, 50);
// Attacker can set imagePath to "../../etc/passwd"
});// User input used in path construction
const userFile = req.query.file;
doc.addImage(`./uploads/${userFile}`, "PNG", 10, 10, 50, 50);
// Attacker can set file to "../../../etc/passwd"// Database value that users can influence
const imagePath = await db.getUserAvatar(userId);
doc.addImage(imagePath, "PNG", 10, 10, 50, 50);Document each instance and classify by risk. Prioritize remediation for code paths where user-controlled data reaches these methods.If the affected methods are exposed but all inputs are validated against an allowlist of permitted paths, the vulnerability cannot be exploited.
Remediation
Update to jsPDF 4.0.0
npm install jspdf@4.0.0Updating to jsPDF 4.0.0 addresses the issue but comes with some caveats:
- It requires Node.js with permission mode, introduced experimentally in v20.0.0 and stable since v22.13.0/v23.5.0/v24.0.0.
- The recommended approach is to use Node's permission flags so the runtime enforces access:
node --permission --allow-fs-read=/path/to/allowed/files ./scripts/generate.js- Be careful not to grant broad read access (e.g., entire filesystem).
- Alternatively, you can allow jsPDF to read specific files by setting jsPDF.allowFsRead in your script, but this is not recommended. See the jsPDF README for details.
What Can Go Wrong
Overly permissive filesystem grants negate the patch. If you upgrade to jsPDF 4.0.0 but configure Node.js with broad read permissions to keep the application running, you remain vulnerable:
# DO NOT DO THIS - grants read access to entire filesystemnode
--permission --allow-fs-read=/* ./server.js# DO NOT DO THIS - grants read access to root and belownode
--permission --allow-fs-read=/ ./server.jsThese configurations allow jsPDF (and any attacker exploiting it) to read any file on the system. The patch provides no protection if the runtime permits unrestricted filesystem access.
Permission mode affects the entire process. Enabling --permission is not scoped to jsPDF alone. Every filesystem read operation in your application requires an explicit grant. Other dependencies, logging, configuration loading, and file uploads may break if their paths aren't included in --allow-fs-read. Audit your application's filesystem access patterns before enabling permission mode in production.
References
- GitHub Security Advisory: https://github.com/parallax/jsPDF/security/advisories/GHSA-f8cm-6447-x5h2
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2025-68428
- jsPDF GitHub Repository: https://github.com/parallax/jsPDF
- Node.js Permissions Documentation: https://nodejs.org/api/permissions.html
Acknowledgements
Credit to Kwangwoon Kim (kilkat) for discovering and responsibly disclosing this vulnerability, and to the jsPDF maintainers for delivering a prompt fix.
Detect and block malware



What's next?
When you're ready to take the next step in securing your software supply chain, here are 3 ways Endor Labs can help:










