Cloudanix VulnDB

CVE-2026-31938

Critical · 9.6

CVSS

9.6

EPSS

0.4%

Published

Mar 18, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A common in-browser PDF tool can be tricked into running untrusted code in a user’s logged-in session if attacker-controlled settings are used when the PDF is created and opened.

Exploitation
Requires User Interaction
Attacker needs
None
Complexity
Moderate
Impact
Data Exposure
Component
Library
Class
XSS
Remediation
Upgrade
Effort
Low
Patch risk
None

What it actually does

jsPDF versions before 4.2.1 fail to sanitize attacker-controlled values in the options argument of output() (and related overloads). Those values can introduce arbitrary HTML and script into the browser document in which the generated PDF is opened, executing as a cross-origin/scope-changing XSS in the victim application origin with access to that origin’s DOM, storage, and reachable secrets. Confidentiality and integrity impact is high; availability impact is limited. CVSS 9.6 (AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L).

Why it matters to the business

Any product that generates PDFs in the browser with jsPDF and forwards untrusted output options can expose users to session theft, unauthorized actions in the user’s account, and leakage of data shown in that origin. The library is widely embedded in web apps, so unpatched dependents inherit the risk even if they did not author the PDF code. The issue is not on CISA KEV, has no public exploit maturity, and EPSS remains low (~0.004) though it rose ~53% over 30 days; combined with CVSS 9.6 and ~194 days since publication, remaining pre-4.2.1 deployments are an overdue patching gap rather than an active mass-exploitation event.

How an attack unfolds

Exploitation requires an application that takes attacker-influenced values (forms, APIs, shared document settings) and passes them unsanitized into jsPDF output options, then a victim who generates and opens the PDF in their browser. Injected script then runs in the victim’s application origin and can read or alter secrets in that context. No named threat actors or ransomware campaigns are associated with this CVE, and public exploit maturity is none; success depends on an app-specific data path, not on a standalone remote exploit against jsPDF itself.

How to fix it

Upgrade the jspdf package to 4.2.1 or later (the version that fixes this issue). If an immediate upgrade is not possible, stop passing any user-controlled data into output() options; allowlist expected fields and treat option values as untrusted. Do not accept client-supplied HTML, document chrome, or type/target-related options. Hunt lockfiles, bundles, and CDNs for jspdf < 4.2.1 and replace transitive copies.

How to confirm the fix worked

Confirm installed and shipped jspdf is 4.2.1 or newer via package lockfiles, SBOM, and production JavaScript bundles. Review all output() call sites and prove no untrusted request or UI field reaches options. After upgrade, regression-test PDF generation with previously accepted untrusted option fields and confirm they are rejected or encoded rather than interpreted as HTML. Use SCA policy to fail builds that still pull jspdf below 4.2.1.

Typical attack path

  1. Locate an application using jsPDF before 4.2.1 that forwards user-supplied values into output() options.
  2. Submit untrusted option values through an exposed input such as a form, query parameter, or API.
  3. Induce or wait for the victim to generate a PDF and open it in the browser.
  4. Injected HTML/script executes in the victim’s application origin.
  5. Attacker uses that origin context to steal session material or act as the victim.

How to detect it

This is client-side XSS; server access logs alone rarely prove exploitation. Prioritize exposure: SBOMs, lockfiles, and bundled JS containing jspdf below 4.2.1. For possible abuse, review application logs and telemetry around PDF generation for unexpected HTML or script-like content in output-option fields, CSP violation reports on PDF preview/download pages, and user reports of unexpected behavior immediately after opening an in-browser PDF. No named APT or ransomware activity is tied to this CVE; treat hits as application-specific input abuse, not a known campaign fingerprint.

What your security team should do

  • Inventory every application and bundle that includes jspdf and flag versions below 4.2.1.
  • Upgrade to jspdf@4.2.1 or later as a priority given CVSS 9.6 and time since publication.
  • Block untrusted input from reaching output() options until upgrades land.
  • Add SCA/SBOM gates so pre-4.2.1 jspdf cannot re-enter CI or production.
  • Brief application owners that this is origin XSS via PDF open-in-browser, not a server RCE, and that user interaction (opening the PDF) is required.

The record

jsPDF is a library to generate PDFs in JavaScript. Prior to version 4.2.1, user control of the `options` argument of the `output` function allows attackers to inject arbitrary HTML (such as scripts) into the browser context the created PDF is opened in. The vulnerability can be exploited in the following scenario: the attacker provides values for the output options, for example via a web interface. These values are then passed unsanitized (automatically or semi-automatically) to the attack victim. The victim creates and opens a PDF with the attack vector using one of the vulnerable method overloads inside their browser. The attacker can thus inject scripts that run in the victims browser context and can extract or modify secrets from this context. The vulnerability has been fixed in jspdf@4.2.1. As a workaround, sanitize user input before passing it to the output method.

Affected packages

Ecosystem Package Introduced Fixed
npm jspdf 0 4.2.1
Chainguard opensearch-dashboards-2-dashboards-notifications 0 2.19.5-r2
Chainguard opensearch-dashboards-2-dashboards-search-relevance 0 2.19.5-r2
Chainguard opensearch-dashboards-2-fips-alerting-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-anomaly-detection-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-maps 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-notifications 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-observability 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-query-workbench 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-reporting 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-search-relevance 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-dashboards-visualizations 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-index-management-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-ml-commons-dashboards 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-security-analytics-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-fips-security-dashboards-plugin 0 2.19.5-r1
Chainguard opensearch-dashboards-2-ml-commons-dashboards 0 2.19.5-r2
Chainguard opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.5-r2
Chainguard opensearch-dashboards-3-alerting-dashboards-plugin 0 3.5.0-r9
Chainguard opensearch-dashboards-3-anomaly-detection-dashboards-plugin 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-maps 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-notifications 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-observability 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-query-workbench 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-reporting 0 3.5.0-r9
Chainguard opensearch-dashboards-3-dashboards-search-relevance 0 3.5.0-r9
Chainguard opensearch-dashboards-3-fips-alerting-dashboards-plugin 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-anomaly-detection-dashboards-plugin 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-maps 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-notifications 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-observability 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-query-workbench 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-reporting 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-dashboards-search-relevance 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-index-management-dashboards-plugin 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-ml-commons-dashboards 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-security-analytics-dashboards-plugin 0 3.5.0-r6
Chainguard opensearch-dashboards-3-fips-security-dashboards-plugin 0 3.5.0-r6
Chainguard opensearch-dashboards-3-index-management-dashboards-plugin 0 3.5.0-r9
Chainguard opensearch-dashboards-3-ml-commons-dashboards 0 3.5.0-r9
Chainguard opensearch-dashboards-3-security-analytics-dashboards-plugin 0 3.5.0-r9
Chainguard opensearch-dashboards-3-security-dashboards-plugin 0 3.5.0-r9
Wolfi opensearch-dashboards-2-dashboards-notifications 0 2.19.5-r2
Wolfi opensearch-dashboards-2-dashboards-search-relevance 0 2.19.5-r2
Wolfi opensearch-dashboards-2-ml-commons-dashboards 0 2.19.5-r2
Wolfi opensearch-dashboards-2-security-analytics-dashboards-plugin 0 2.19.5-r2
Wolfi opensearch-dashboards-3-alerting-dashboards-plugin 0 3.5.0-r9
Wolfi opensearch-dashboards-3-anomaly-detection-dashboards-plugin 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-maps 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-notifications 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-observability 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-query-workbench 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-reporting 0 3.5.0-r9
Wolfi opensearch-dashboards-3-dashboards-search-relevance 0 3.5.0-r9
Wolfi opensearch-dashboards-3-index-management-dashboards-plugin 0 3.5.0-r9
Wolfi opensearch-dashboards-3-ml-commons-dashboards 0 3.5.0-r9
Wolfi opensearch-dashboards-3-security-analytics-dashboards-plugin 0 3.5.0-r9
Wolfi opensearch-dashboards-3-security-dashboards-plugin 0 3.5.0-r9

Related vulnerabilities