Safeguard
Open Source

Is the jsPDF npm Package Safe? A Security Review

The jsPDF npm package is widely used for client-side PDF generation, but recent path traversal and ReDoS advisories mean the version you pin matters. Here is what to check.

Priya Mehta
Security Analyst
6 min read

The jsPDF npm package is generally safe for browser-side PDF generation, but only if you are on version 4.0.0 or later and you never pass untrusted input into its image, HTML, or font loading methods. Two 2025 advisories changed the calculus for anyone shipping jspdf in production, and a third landed in early 2026. If you installed npm jspdf years ago and never touched the version, you are almost certainly exposed to at least one of them.

jsPDF is a mature, popular library. That popularity is exactly why it is worth reviewing: a single vulnerable transitive copy can sit three levels deep in your dependency tree and never show up in a casual package.json skim.

What jsPDF actually does

jsPDF turns JavaScript into PDF documents entirely in the client or in Node. You call new jsPDF(), add text, images, and vector shapes, then call .save() or .output(). Teams reach for it because it avoids a server round-trip for report generation. The companion module, jspdf-autotable npm, adds table rendering on top of the core API and is frequently installed alongside it.

The security-relevant surface is the set of methods that accept a source for external content: addImage, html, addSvgAsImage, addFont, and in Node builds, loadFile. Every serious jsPDF advisory so far traces back to one of these.

CVE-2025-29907: ReDoS through addImage

Disclosed in March 2025, CVE-2025-29907 is a regular expression denial-of-service (ReDoS) issue. When user-controlled input reaches the first argument of addImage (and by extension html and addSvgAsImage), a crafted data URL can drive CPU usage to a standstill. A single malicious request can pin a core.

The fix shipped in jsPDF 3.0.1. If you cannot upgrade immediately, sanitize or validate any image URL before it reaches addImage:

function isSafeImageUrl(url) {
  // reject overly long data URLs and anything you did not originate
  return typeof url === "string" && url.length < 5_000_000 &&
    (url.startsWith("data:image/") || url.startsWith("https://cdn.example.com/"));
}

CVE-2025-68428: path traversal in Node builds

The more serious of the two is CVE-2025-68428, a local file inclusion / path traversal flaw carrying a CVSS v4.0 score of 9.2. It affects only the Node.js builds (dist/jspdf.node.js and its minified sibling), not the browser bundle.

The root cause is straightforward: when a user controls the first argument of loadFile in the Node build, jsPDF resolved the path with path.resolve() and read it with fs.readFileSync() — no directory confinement. An attacker supplying ../../../../etc/passwd (or a cloud instance metadata path) could read arbitrary files. The same underlying loader backs addImage, html, and addFont, so all four are affected.

The patch landed in jsPDF 4.0.0, which locks file system access by default. You now opt in explicitly:

import { jsPDF } from "jspdf";

const doc = new jsPDF({
  // whitelist exactly what the library may read
  allowFsRead: ["./assets/logo.png", "./fonts/Inter.ttf"],
});

You can also rely on Node's own permission model with --allow-fs-read. Either way, the days of jsPDF reading anything the process user can are over — provided you upgrade.

CVE-2026-24133 and the pattern

In early 2026 a further denial-of-service advisory, CVE-2026-24133, was published for unvalidated BMP dimensions in the library's BMP decoder. The details differ, but the theme is identical to the earlier two: untrusted content flowing into a parser without bounds. That is the mental model to carry when you review jsPDF usage in your own code — treat every source argument as hostile until proven otherwise.

How to audit your dependency for jspdf npm

Start by finding every copy, including transitive ones:

npm ls jspdf
# or, to see why it is installed
npm explain jspdf

If npm ls shows more than one version, a transitive dependency (a charting library, a reporting widget) is pulling an old copy that your top-level upgrade will not touch. This is the classic blind spot: your package.json says "jspdf": "^4.0.0" but a nested node_modules/some-widget/node_modules/jspdf is still on 2.x. An SCA tool such as Safeguard will flag this transitively rather than trusting your declared version. For a deeper look at how nested copies hide, our write-up on software composition analysis covers lockfile-level resolution.

Then pin deliberately:

npm install jspdf@^4.0.0
npm audit

npm audit will surface the known advisories, but note that it keys off the resolved version in your lockfile, so run it after the install completes.

Safe-usage checklist

A few practices keep jsPDF boring, which is what you want from a PDF library:

  • Stay on 4.0.0+ and let Dependabot or Renovate keep it current.
  • Never pass raw user input to addImage, html, addSvgAsImage, addFont, or loadFile. Validate the origin first.
  • In Node, set allowFsRead to an explicit allowlist and run with --allow-fs-read scoping.
  • Prefer the browser build when you do not need server-side rendering — it has a smaller attack surface because it lacks the file system loader entirely.
  • Bound the size and count of images you accept before rendering, which blunts both the ReDoS and BMP DoS classes.

If your team is comparing scanners for catching exactly this kind of transitive drift, our comparison with Snyk walks through how different tools resolve nested npm versions.

FAQ

Is jsPDF safe to use in production?

Yes, on version 4.0.0 or later and with untrusted input kept out of its source-accepting methods. The 2025 advisories were serious but are fixed in current releases. Pin the version and monitor for new advisories.

What is the difference between the jsPDF browser and Node builds?

The Node build includes a file system loader (loadFile) that the browser build lacks. CVE-2025-68428, the path traversal, affects only the Node builds. If you do not need server-side file loading, the browser build has a smaller attack surface.

Does jspdf-autotable have its own vulnerabilities?

jspdf-autotable is a rendering plugin that delegates to core jsPDF for the risky operations, so keeping the core jspdf dependency patched is what matters most. Still, check npm ls jspdf-autotable and keep it current too.

How do I find old jsPDF versions in my project?

Run npm ls jspdf to see every resolved copy, including transitive ones pulled in by other packages. If multiple versions appear, a nested dependency is holding an outdated copy that your top-level upgrade will not fix on its own.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.