CVE-2026-31898
High · 8.1CVSS
8.1
EPSS
0.6%
Published
Mar 18, 2026
CISA due date
—
Cloudanix analysis
A common PDF-making library can hide extra instructions in files built from untrusted text, so those documents might run unwanted commands when someone opens them.
- Exploitation
- Requires User Interaction
- Attacker needs
- None
- Complexity
- Low
- Impact
- Full Compromise
- Component
- Library
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Low
- Patch risk
- Low
What it actually does
jsPDF versions before 4.2.1 fail to sanitize the color argument of createAnnotation, so attacker-controlled strings can be written into the PDF object graph as extra dictionaries and actions. Injected objects can include JavaScript and other PDF actions that a viewer may run when the file is opened or when the annotation is used, breaking the integrity of generated documents and enabling script execution inside the PDF reader.
Why it matters to the business
Apps that build PDFs from untrusted input (exports, invoices, tickets, reports) can issue files that harm recipients or abuse trust in your brand. Consequences include data or credential theft in viewers that honor PDF JavaScript, help-desk and incident cost from malicious attachments, and compliance or customer-trust damage. The issue is not in CISA KEV, is not tied to ransomware, and has no public exploit, but EPSS rose about 74% over 30 days and the CVE is months old—treat unpatched user-driven PDF generation as a high-severity patch, not an emergency KEV outage.
How an attack unfolds
An attacker finds a feature that uses jsPDF and passes user-influenced values into createAnnotation, especially color, without allowlisting. They submit input that breaks out of the intended color value and appends extra PDF objects such as JavaScript actions. The application embeds that input in a generated PDF and delivers it (download, email, or store). When a victim opens or interacts with the file in a viewer that executes PDF JavaScript or annotation actions, the injected action runs in the reader, which the attacker can abuse for further social engineering or data access in permissive viewers. No named threat actors are associated with this CVE.
How to fix it
Upgrade jsPDF (parall/jspdf) to 4.2.1 or later, which fixes createAnnotation handling. If you cannot upgrade immediately, treat every user-controlled argument to createAnnotation—especially color—as untrusted: allowlist expected color formats only, reject PDF token and dictionary syntax, and never concatenate raw user strings into PDF output. Inventory direct and transitive uses in browsers and Node.js, including lockfiles and container images, and apply the same upgrade. Re-generate or quarantine PDFs produced on vulnerable versions if they may contain untrusted annotation data.
How to confirm the fix worked
Confirm jsPDF 4.2.1 or newer in package manifests, lockfiles, and runtime module metadata. Review all createAnnotation call sites and related annotation APIs for user-controlled color and other fields, and enforce allowlists. In a non-production test environment, submit unusual but non-weaponized color values (special characters, dictionary-like text) and verify they are escaped or rejected rather than appearing as extra PDF objects. Sample generated PDFs and confirm they contain only the JavaScript or open/annotation actions your application intentionally adds.
Typical attack path
- Find a client- or server-side flow that generates PDFs with jsPDF and accepts user-influenced annotation or color data.
- Submit unsanitized input intended to break out of the color value and inject extra PDF objects, including JavaScript or other actions.
- Cause the application to generate and store, download, or email the resulting PDF.
- Get a victim to open or interact with the PDF in a viewer that honors PDF JavaScript or annotation actions.
- Abuse the executed action and the organization’s branding on the document for further harm to the victim or the issuer.
How to detect it
This is injection at PDF generation time, so evidence is in produced files and generation logs, not a distinct network exploit service. Review PDFs created before the upgrade that included user-controlled annotation or styling fields, and parse object trees for JavaScript actions, open actions, and annotation additional-actions the business logic did not add. Correlate with access logs to PDF-generation endpoints for anomalous color or annotation parameters. Check package-manager, CI, and image history for jsPDF below 4.2.1 as exposure context, not proof of compromise. Email-gateway, DLP, and endpoint telemetry that flags PDF JavaScript or unexpected script prompts on internally generated attachments can indicate delivery. No named APT or ransomware campaign is reported for this CVE.
- /S /JavaScript
- /S/JavaScript
- /JS (
- /JS(
- /OpenAction
- /AA <<
- /AA<<
- /A <</S
- /Type /Annot
What your security team should do
- Upgrade jsPDF to 4.2.1+ on every user-driven or internet-facing PDF generation path, including transitive dependencies.
- Inventory createAnnotation and other user-influenced PDF APIs; allowlist color and annotation fields until patched.
- Hunt historically generated PDFs and mail/export logs for unexpected JavaScript or open/annotation actions per detection guidance.
- There is no CISA KEV due date or known ransomware use; complete the upgrade under your high-severity SLA and do not defer it because exploit maturity is currently none.
- Re-issue or quarantine PDFs created from untrusted input while vulnerable versions were deployed, and brief document-handling teams that internally generated PDFs are not inherently safe until then.
The record
jsPDF is a library to generate PDFs in JavaScript. Prior to version 4.2.1, user control of arguments of the `createAnnotation` method allows users to inject arbitrary PDF objects, such as JavaScript actions. If given the possibility to pass unsanitized input to the following method, a user can inject arbitrary PDF objects, such as JavaScript actions, which might trigger when the PDF is opened or interacted with the `createAnnotation`: `color` parameter. The vulnerability has been fixed in jsPDF@4.2.1. As a workaround, sanitize user input before passing it to the vulnerable API members.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | jspdf | 0 | 4.2.1 |
| 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-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
- GHSA-7x6v-j9x4-qf24 jsPDF has a PDF Object Injection via FreeText color Same vulnerability
- CVE-2026-31938 jsPDF is a library to generate PDFs in JavaScript. Also affects jspdf
- GHSA-wfv2-pwc8-crg5 jsPDF has HTML Injection in New Window paths Also affects jspdf
- GHSA-p5xg-68wr-hm3m jsPDF has a PDF Injection in AcroForm module allows Arbitrary JavaScript Execution… Also affects jspdf
- GHSA-9vjf-qc39-jprp jsPDF has a PDF Object Injection via Unsanitized Input in addJS Method Also affects jspdf
- CVE-2026-25940 jsPDF is a library to generate PDFs in JavaScript. Also affects jspdf
- GHSA-67pg-wm7f-q7fj jsPDF Affected by Client-Side/Server-Side Denial of Service via Malicious GIF Dimensions Also affects jspdf
- CVE-2026-25755 jsPDF is a library to generate PDFs in JavaScript. Also affects jspdf