
Co znajdziesz w tym artykule?
- 1 Wprowadzenie do problemu / definicja luki
- 2 W skrócie
- 3 Kontekst / historia / powiązania
- 4 Analiza techniczna / szczegóły luki
- 5 Praktyczne konsekwencje / ryzyko
- 6 Rekomendacje operacyjne / co zrobić teraz
- 7 Różnice / porównania z innymi przypadkami
- 8 Podsumowanie / kluczowe wnioski
- 9 Źródła / bibliografia
Wprowadzenie do problemu / definicja luki
W bibliotece jsPDF wykryto krytyczną podatność typu Local File Inclusion / Path Traversal, oznaczoną jako CVE-2025-68428. Problem dotyczy wyłącznie buildów Node.js i pozwala atakującemu odczytywać dowolne pliki dostępne dla procesu Node, a następnie „przemycać” ich zawartość wygenerowanym PDF-em (czyli w legalnym artefakcie wyjściowym aplikacji).
W skrócie
- Co jest podatne: jsPDF w wersjach < 4.0.0, tylko artefakty
dist/jspdf.node.jsidist/jspdf.node.min.js. - Warunek ataku: użytkownik/atakujący musi mieć możliwość sterowania argumentem-ścieżką pliku przekazywanym do podatnych metod (bez twardego allowlistu/sanitizacji).
- Skutek: wyciek tajnych danych (np. pliki konfiguracyjne, sekrety, klucze, pliki
.env) do PDF, który aplikacja normalnie zwraca/zapisuje. - Poprawka: aktualizacja do jsPDF 4.0.0, gdzie domyślnie ograniczono dostęp do systemu plików i oparto egzekwowanie na Node.js Permission Model.
Kontekst / historia / powiązania
Podatność została zgłoszona w procesie GitHub Security Advisories (GHSA) i oceniona jako krytyczna (CNA score 9.2 w CVSS v4).
BleepingComputer zwraca uwagę, że ryzyko realnej eksploatacji zależy od tego, czy ścieżki plików są kontrolowane przez użytkownika, a także że w praktyce wdrożenie mitigacji przez Permission Model może wymagać nowszych wersji Node.
Analiza techniczna / szczegóły luki
Co dokładnie nie działa
Sednem problemu jest metoda loadFile w buildzie Node.js: jeśli atakujący kontroluje pierwszy argument (ścieżkę), biblioteka potrafi odczytać wskazany plik z dysku i dołączyć jego zawartość do PDF.
Metody podatne (wektory wejścia)
Oprócz loadFile, podatne są też metody, które pośrednio z niej korzystają:
addImagehtmladdFont
Przykładowy wektor ataku (model)
Jeśli aplikacja pozwala użytkownikowi wskazać „obrazek” lub zasób do osadzenia w PDF (np. parametr imagePath), atakujący może zamiast tego podać ścieżkę do pliku z sekretami. Zawartość trafi do PDF „jakby nigdy nic”, a następnie wycieknie kanałem dystrybucji dokumentu (download, email, storage, S3 itp.).
Dlaczego poprawka jest „nietypowa”
W jsPDF 4.0.0 ograniczenie dostępu do systemu plików jest domyślne, a rekomendowana ochrona opiera się na Node.js Permission Model (uruchomienie procesu z flagą --permission i precyzyjnymi allowlistami zasobów).
Praktyczne konsekwencje / ryzyko
Największe ryzyko dotyczy usług, które:
- generują PDF-y po stronie serwera (Node.js),
- przyjmują od użytkownika parametry wpływające na to, jakie pliki/zasoby są osadzane (np. „logo”, „załącznik”, „szablon”, „font”, „HTML do renderu”),
- działają z szerokimi uprawnieniami do systemu plików lub z dostępnymi sekretami na dysku (np.
.env, klucze prywatne, konfiguracje).
Warto też zauważyć „cichy” charakter eksfiltracji: to nie musi być osobny kanał C2 – dane mogą wyciec w legalnym pliku PDF, który system i monitoring traktują jako normalny rezultat pracy aplikacji.
Rekomendacje operacyjne / co zrobić teraz
1) Aktualizacja zależności (priorytet)
- Zaktualizuj do
jspdf@4.0.0(lub nowszej).
2) Wymuś Permission Model w Node.js (jeśli generujesz PDF-y na serwerze)
Uruchamiaj proces z ograniczeniami i minimalnym zakresem odczytu:
node --permission --allow-fs-read=/app/assets,/app/templates ./server.js
Flagi --allow-fs-read i --permission są elementem Permission Model (zwróć uwagę: zbyt szerokie reguły, np. --allow-fs-read=*, de facto kasują ochronę).
Uwaga operacyjna: te flagi dotyczą całego procesu Node, nie tylko jsPDF — mogą ujawnić ukryte zależności od dostępu do FS i wywołać regresje.
3) Jeśli nie możesz zaktualizować natychmiast
- Wprowadź twardy allowlist (mapowanie identyfikator → bezpieczna ścieżka) zamiast przepuszczać ścieżki od użytkownika.
- Zablokuj sekwencje path traversal (
../,..\\) i używaj normalizacji (path.resolve) + sprawdzania prefiksu katalogu bazowego. - Rozdziel role: osobny serwis do generowania PDF z minimalnymi uprawnieniami i bez sekretów na dysku.
4) Szybkie „triage” ekspozycji w kodzie
Szukaj wywołań:
addImage(...),html(...),addFont(...),loadFile(...)
gdzie pierwszy argument może pochodzić z: request params, body, query string, upload metadata, bazy danych modyfikowalnej przez userów.
Różnice / porównania z innymi przypadkami
- Klasyczne LFI/Path Traversal często kończy się odpowiedzią HTTP z treścią pliku lub błędem. Tutaj wyciek jest „opakowany” w PDF, który bywa logowany, archiwizowany i wysyłany dalej — co utrudnia wykrycie i zwiększa promień rażenia (retencja, kopie, systemy DLP).
- Nietypowe jest też oparcie remediacji na mechanizmie runtime (Permission Model) zamiast wyłącznie na walidacji wejścia w bibliotece — co zwiększa znaczenie poprawnej konfiguracji środowiska uruchomieniowego.
Podsumowanie / kluczowe wnioski
- CVE-2025-68428 to krytyczna podatność w jsPDF (Node build) umożliwiająca odczyt lokalnych plików i ich eksfiltrację przez generowane PDF-y.
- Jeżeli w Twojej aplikacji użytkownik może wpływać na ścieżki/zasoby przekazywane do
addImage/html/addFont/loadFile, traktuj temat jako pilny. - Najlepsza ścieżka: upgrade do 4.0.0 + uruchamianie Node z
--permissioni wąskimi allowlistami FS.
Źródła / bibliografia
- GitHub Security Advisory (jsPDF) – GHSA-f8cm-6447-x5h2 (GitHub)
- NVD (NIST) – CVE-2025-68428 (NVD)
- Endor Labs – analiza i rekomendacje dla CVE-2025-68428 (endorlabs.com)
- Node.js Documentation – Permission Model / flags
--permission,--allow-fs-read(Node.js) - BleepingComputer – kontekst i ryzyka wdrożeniowe mitigacji (BleepingComputer)