DEV Community

CVE Reports
CVE Reports

Posted on • Originally published at cvereports.com

CVE-2026-22787: Print to Pwned: The DOM XSS Inside html2pdf.js

Print to Pwned: The DOM XSS Inside html2pdf.js

Vulnerability ID: CVE-2026-22787
CVSS Score: 8.7
Published: 2026-01-14

A high-severity Cross-Site Scripting (XSS) vulnerability in the popular html2pdf.js library allows attackers to execute arbitrary JavaScript by injecting malicious HTML strings during PDF generation.

TL;DR

The html2pdf.js library (versions < 0.14.0) attempted to sanitize HTML input by manually removing tags <em>after</em> adding them to the DOM. This &#39;blacklist&#39; approach failed spectacularly because inline event handlers (like onerror) execute immediately upon parsing. The fix involves implementing DOMPurify to whitelist safe HTML before it ever touches the document.</p> <hr> <h3> <a name="exploit-status-poc" href="#exploit-status-poc" class="anchor"> </a> ⚠️ Exploit Status: POC </h3> <h2> <a name="technical-details" href="#technical-details" class="anchor"> </a> Technical Details </h2> <ul> <li><strong>CWE ID</strong>: CWE-79 (Improper Neutralization of Input During Web Page Generation)</li> <li><strong>Attack Vector</strong>: Network (Client-Side)</li> <li><strong>CVSS v4.0</strong>: 8.7 (High)</li> <li><strong>Impact</strong>: High Confidentiality, High Integrity</li> <li><strong>Exploit Status</strong>: PoC Available / Trivial</li> <li><strong>Affected Component</strong>: src/utils.js:createElement</li> </ul> <h2> <a name="affected-systems" href="#affected-systems" class="anchor"> </a> Affected Systems </h2> <ul> <li>Web applications using html2pdf.js &lt; 0.14.0</li> <li>Single Page Applications (SPAs) generating client-side reports</li> <li>Invoice generators</li> <li>Ticket/Receipt printing services</li> <li><strong>html2pdf.js</strong>: &lt; 0.14.0 (Fixed in: <code>0.14.0</code>)</li> </ul> <h2> <a name="code-analysis" href="#code-analysis" class="anchor"> </a> Code Analysis </h2> <h3> <a name="commit-988826e" href="#commit-988826e" class="anchor"> </a> Commit: <a href="https://github.com/eKoopmans/html2pdf.js/commit/988826e336035b39a8608182d7b73c0e3cd78c7b">988826e</a> </h3> <p>Fix: sanitize text source (resolve #865)<br> </p> <div class="highlight"><pre class="highlight diff"><code><span class="gd">- if (opt.innerHTML) { - el.innerHTML = opt.innerHTML; - var scripts = el.getElementsByTagName('script'); - for (var i = scripts.length; i-- &gt; 0; null) { - scripts[i].parentNode.removeChild(scripts[i]); - } - } </span><span class="gi">+ if (opt.innerHTML) el.innerHTML = DOMPurify.sanitize(opt.innerHTML); </span></code></pre></div> <p></p> <h2> <a name="exploit-details" href="#exploit-details" class="anchor"> </a> Exploit Details </h2> <ul> <li><a href="https://github.com/eKoopmans/html2pdf.js/issues/865">GitHub Issue</a>: Original bug report demonstrating XSS via string input</li> <li><a href="https://dev.toN/A">PoC</a>: html2pdf().from(&#39;<img src=x onerror=alert(1)>&#39;).save()</li> </ul> <h2> <a name="mitigation-strategies" href="#mitigation-strategies" class="anchor"> </a> Mitigation Strategies </h2> <ul> <li>Upgrade html2pdf.js to version 0.14.0 or later immediately.</li> <li>Implement Content Security Policy (CSP) headers to restrict script execution sources.</li> <li>Sanitize user input on the server-side as a defense-in-depth measure.</li> <li>Avoid passing raw strings to the <code>.from()</code> method; pass sanitized DOM nodes instead.</li> </ul> <p><strong>Remediation Steps:</strong></p> <ol> <li>Run <code>npm install html2pdf.js@latest</code> or <code>yarn upgrade html2pdf.js</code>.</li> <li>Verify that <code>package.json</code> reflects version <code>^0.14.0</code>.</li> <li>Audit your codebase for usage of <code>html2pdf().from(variable)</code>. Ensure <code>variable</code> is not raw user input.</li> <li>Rebuild and deploy your application assets.</li> </ol> <h2> <a name="references" href="#references" class="anchor"> </a> References </h2> <ul> <li><a href="https://github.com/eKoopmans/html2pdf.js/security/advisories/GHSA-w8x4-x68c-m6fc">GHSA Advisory</a></li> <li><a href="https://github.com/eKoopmans/html2pdf.js/pull/877">Pull Request #877</a></li> </ul> <hr> <p><em><a href="https://cvereports.com/reports/CVE-2026-22787">Read the full report for CVE-2026-22787 on our website</a> for more details including interactive diagrams and full exploit analysis.</em></p>

Top comments (0)