CVE-2026-22787: 
JavaScript vulnerability analysis and mitigation

Overview

CVE-2026-22787 is a Cross-Site Scripting (XSS) vulnerability in the html2pdf.js npm library (by eKoopmans) that allows arbitrary JavaScript execution in a victim's browser when unsanitized text is passed as a source to the library's conversion functions. All versions prior to 0.14.0 are affected. The vulnerability was initially reported on November 21, 2025, and publicly disclosed via GitHub Security Advisory GHSA-w8x4-x68c-m6fc on January 14, 2026. It carries a CVSS v3.1 score of 6.1 (Medium) and a CVSS v4.0 score of 8.7 (High) (GitHub Advisory, NVD).

Technical details

The root cause is CWE-79 (Improper Neutralization of Input During Web Page Generation), specifically in src/worker.js at line 71, where the Worker.prototype.from() method directly assigns a user-supplied string to the innerHTML property of a newly created div element without adequate sanitization (GitHub Issue #865). A partial mitigation existed in src/utils.js that stripped <script> tags, but this was insufficient because it did not block event handler attributes (e.g., onerror, onload), SVG-embedded scripts, or iframe JavaScript URLs — and script removal occurred after innerHTML assignment, meaning event handlers were already registered (GitHub Issue #865). An attacker can exploit this by passing a malicious HTML string (e.g., <img src=x onerror="alert(document.cookie)">) to html2pdf() or html2pdf().from(), which is then appended to the DOM and triggers script execution in the user's browser context (GitHub Advisory).

Impact

Successful exploitation allows an attacker to execute arbitrary JavaScript in the context of the victim's browser session, enabling session cookie theft, credential harvesting, unauthorized actions on behalf of the user, and modification of page content. The vulnerability affects confidentiality and integrity of the vulnerable system's data (rated High in CVSS v4.0), with a low availability impact. Because the attack is client-side, the scope is limited to the browser context of users interacting with applications that pass unsanitized input to html2pdf.js (GitHub Advisory, NVD).

Exploitability

A proof-of-concept exploit is publicly available, published by the original reporter (aydinnyunus) at a GitHub.io blog post referenced in NVD (NVD). The vulnerability requires no authentication and no special privileges, though it does require passive user interaction (a user must trigger the pdf generation with attacker-controlled input). The EPSS score is approximately 0.051% (0.000510), indicating low current exploitation probability. There is no evidence of active in-the-wild exploitation or threat actor attribution at this time, and the vulnerability is not listed in the CISA KEV catalog (Feedly). The vulnerability is detectable by Qualys scanner (detection ID: 5007001).

Exploitation steps

  1. Identify a target application: Find a web application that uses html2pdf.js versions prior to 0.14.0 and passes user-controlled input as a string source to html2pdf() or html2pdf().from().
  2. Craft a malicious payload: Prepare an HTML string containing an XSS payload that bypasses the library's partial <script> tag removal, such as an event-handler-based payload:
    const maliciousHTML = '<img src=x onerror="alert(document.cookie)">';
  3. Inject the payload: Supply the malicious string as input to the application in a way that it gets passed to the html2pdf.js function, e.g., via a form field, URL parameter, or API call that the application forwards to html2pdf(maliciousHTML) or html2pdf().from(maliciousHTML).
  4. Trigger DOM injection: When the application calls html2pdf.js with the attacker-controlled string, the library assigns it to innerHTML of a div element (src/worker.js line 71) and appends it to the DOM (src/worker.js line 125).
  5. Achieve script execution: The browser parses the injected HTML, registers the event handler (e.g., onerror), and fires it when the element is added to the DOM — executing the attacker's JavaScript in the victim's browser context, enabling cookie theft, session hijacking, or further malicious actions (GitHub Issue #865, NVD).

Indicators of compromise

  • Logs: Application logs showing unexpected or malformed HTML strings (containing onerror, onload, onclick, <svg>, <iframe> with javascript: URLs) being submitted as input to PDF generation endpoints.
  • Network: Outbound requests from the victim's browser to attacker-controlled domains (e.g., for cookie exfiltration) originating from pages that invoke html2pdf.js; unusual POST requests carrying encoded HTML payloads to PDF generation APIs.
  • File System / Dependencies: Presence of html2pdf.js npm package versions below 0.14.0 in package.json or package-lock.json ("html2pdf.js": "<0.14.0").
  • Browser/Client Behavior: Unexpected JavaScript alert dialogs or network requests to unknown domains triggered during PDF generation workflows in the browser.

Mitigation and workarounds

Upgrade html2pdf.js to version 0.14.0 or later, which integrates DOMPurify to sanitize all text-source input before DOM insertion (commit 988826e) (GitHub PR #877, GitHub Advisory). For applications that cannot immediately upgrade, manually sanitize all user-supplied strings with DOMPurify before passing them to any html2pdf.js function: html2pdf().from(DOMPurify.sanitize(userInput)).save(). Additionally, implementing a strict Content Security Policy (CSP) header can reduce the impact of any XSS execution by restricting inline script and event handler execution.

Community reactions

The vulnerability was reported by security researcher aydinnyunus, who also published a detailed write-up and proof-of-concept on their GitHub.io blog (NVD). The eKoopmans maintainer responded promptly, merging the fix within approximately two months of the initial report and releasing version 0.14.0 with no other breaking changes (GitHub PR #877). The vulnerability received coverage from security aggregators including Red Hat, INCIBE, VulnDB, and GitLab Advisories, reflecting moderate community interest given the library's wide usage (4.9k GitHub stars, 1.5k forks).

Additional resources


Source: This report was generated using AI

Related JavaScript vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

GHSA-966w-4vpf-p7hcHIGH7.1
  • JavaScript logoJavaScript
  • @aloma.io/aloma
NoYesOct 25, 2026
GHSA-mrwp-f3q8-3g9pMEDIUM5.9
  • JavaScript logoJavaScript
  • follow-redirects
NoYesOct 25, 2026
GHSA-hfm3-x63j-7fxpHIGHN/A
  • JavaScript logoJavaScript
  • @payload-auth-link/migrate
NoYesOct 25, 2026
GHSA-6244-vvv9-76f5MEDIUMN/A
  • JavaScript logoJavaScript
  • @payload-auth-link/plugin
NoYesOct 25, 2026
GHSA-q53q-qg98-p9jfHIGHN/A
  • JavaScript logoJavaScript
  • llm-fw
NoYesOct 25, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Additional Wiz resources

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management