Sanityzacja niezaufanych plików PDF: rozbrajanie i rekonstrukcja treści
Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4
W skrócie
Dział zatytułowany „W skrócie”PDF, który przybywa ze świata zewnętrznego, jest kodem w równym stopniu, co dokumentem. Może nieść JavaScript, akcję Launch, osadzony plik wykonywalny oraz strukturę spreparowaną, by potknąć parser. Rozbrajanie i rekonstrukcja treści (CDR, Content Disarm & Reconstruction) traktuje ten plik jako niezaufany, zachowuje tylko to, co bezpieczne, i odbudowuje czysty PDF z ocalałych.
Ta strona wyjaśnia, jak CdrEngine z NextPDF Enterprise to robi — oraz jedną
uczciwą rzecz, którą każdy dostawca CDR powinien powiedzieć na głos: odbudowany
plik to projekcja bezpieczeństwa oryginału, a nie jego wierna kopia.
Dlaczego to ma znaczenie
Dział zatytułowany „Dlaczego to ma znaczenie”Niebezpieczne części PDF nie są egzotyczne. To standardowe funkcje. Specyfikacja definiuje cały katalog akcji — co się dzieje, gdy dokument się otwiera, gdy strona jest pokazywana, gdy pole się zmienia — a ten katalog obejmuje akcje JavaScript i Launch (Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4). Czytnik, który honoruje format, ochoczo je uruchomi. To przyczółek napastnika: plik jednocześnie doskonale poprawny i doskonale złośliwy.
Filtrowanie po rozszerzeniu pliku nic tu nie daje. Zagrożenie jest wewnątrz dobrze uformowanego PDF, więc jedyną realną obroną jest otworzyć go, zrozumieć i zdjąć aktywną maszynerię, zanim w ogóle dotrze do renderera. To postawa walidacji danych wejściowych, którą opisują wytyczne OWASP dotyczące przesyłania plików i walidacji danych wejściowych: nigdy nie ufaj bajtom i przedkładaj odbudowę znanego-dobrego artefaktu nad skanowanie wrogiego w poszukiwaniu znanych-złych sygnatur.
Wersja skrócona
Dział zatytułowany „Wersja skrócona”- CDR zakłada, że dane wejściowe są wrogie, i wytwarza nowy plik, zamiast łatać stary.
CdrEngine::sanitize()uruchamia sześć faz: parsowanie, kontrola dopuszczenia, wykrywanie zagrożeń, filtrowanie, czyszczenie odwołań, odbudowa.- Zwraca
CdrResult, który mówi ci, co usunięto, czy dokument w ogóle został dopuszczony oraz — jeśli nie — dlaczego został odrzucony. - Wyjście to projekcja bezpieczeństwa. Jawnie nie jest kopią dowodową, dopasowaniem skrótu ani artefaktem archiwalnym. To umowa, a nie zastrzeżenie.
- To wyłącznie Enterprise. Edycja podstawowa NextPDF nie wykonuje CDR.
Jak podchodzi do tego NextPDF
Dział zatytułowany „Jak podchodzi do tego NextPDF”Własna dokumentacja silnika podaje projektową czerwoną linię w trzech słowach:
Security Projection Layer. sanitize() to destrukcyjna, nieodwracalna
transformacja. Wolno jej wyrzucać bajty. Czego jej nie wolno, to udawać, że
wynik jest tym samym dokumentem.
Potok jest celowo uporządkowany. Każda faza zawęża zaufanie, zanim następna faza na nim zadziała.
- ParsePdfReader builds the object graph from the raw bytes. A parse failure is a rejection, not a best-effort guess.
- Admission controlResource limits are checked first — object count, page count, decoded-stream size, per-stream inflation ratio. Over-budget input is rejected, never sanitised.
- DetectThreatDetector walks the graph and records each dangerous feature as a DetectedThreat with its object number and type.
- FilterObjects are partitioned into safe and removed. Catalog-level keys are stripped in place so the document catalog itself survives.
- Reference scrubPointers to removed objects are cleaned so the rebuilt file has no dangling references.
- RebuildCdrRebuilder serialises only the safe objects into a new PDF. The output is fresh structure, not an edited original.
Dopuszczenie przed rozbrojeniem. Zanim usunięte zostanie pojedyncze
zagrożenie, silnik pyta, czy dokument jest w ogóle wart przetwarzania.
CdrPolicy niesie limity — maxObjects, maxPageCount, maxDecodedStreamBytes
oraz maxInflationRatio, który broni przed bombami dekompresyjnymi. Dokument,
który je przekracza, jest odrzucany, a CdrResult mówi to za pomocą
admitted: false oraz rejectionReason. To rozróżnienie jest nośne: „oczyściliśmy
go” i „odmówiliśmy mu” to różne wyniki, a typ wyniku trzyma je osobno, by twoje
raportowanie błędów też mogło.
Zagrożenia są nazywane, a nie zgadywane. ThreatDetector::detect()
odwzorowuje każdą niebezpieczną konstrukcję na ThreatType — JavaScript,
LaunchAction, OpenAction, AdditionalActions, RemoteGoTo, SubmitForm,
ImportData, EmbeddedFiles, RichMedia, NamedJavaScript i więcej — z
których każdy jest związany z konkretną funkcją PDF. Obiekt, którego nie da się w
ogóle sparsować, staje się własnym typem zagrożenia, UnparseableObject,
ponieważ obiekt, którego sanityzator nie potrafi odczytać, jest obiektem, za
który nie potrafi ręczyć. Każde znalezisko to DetectedThreat niosący numer
obrażającego obiektu, więc usunięcie jest precyzyjne.
Usuwanie chroni dokument, a nie tylko ładunek. Niektóre niebezpieczne klucze
żyją w katalogu dokumentu (Root) — na przykład /OpenAction, który odpala przy
otwarciu. Usunięcie całego obiektu Root, by zabić jeden klucz, zniszczyłoby
katalog i po cichu zepsuło plik. Silnik obsługuje je zamiast tego jako zdjęcia
klucza w miejscu na katalogu i, jako zabezpieczenie zawodzące bezpiecznie,
odmawia wyemitowania odbudowanego dokumentu, który w ogóle utracił swój /Root.
Sanityzator, który wytwarza strukturalnie zepsuty plik, raportując sukces, to
dokładnie ten tryb awarii, któremu to zabezpieczenie ma zapobiegać.
Praktyczny przykład
Dział zatytułowany „Praktyczny przykład”Poniższy kształt to prawdziwy punkt wejścia. Wręczasz silnikowi surowe bajty i
politykę; odzyskujesz CdrResult, który jest uczciwy co do tego, co się stało.
<?php
declare(strict_types=1);
use NextPDF\Enterprise\Security\Cdr\CdrEngine;use NextPDF\Enterprise\Security\Cdr\CdrPolicy;
$engine = new CdrEngine();
// Standard policy removes the known active threats — JavaScript, Launch// actions, remote go-to, form submit/import, and the rest — while leaving// the lossy opt-in "Strip*" cases off by default.$result = $engine->sanitize($untrustedPdfBytes, CdrPolicy::standard());
if (!$result->admitted) { // Rejected by admission control (e.g. object/page limit, zip bomb). // This is NOT a sanitised document. Do not serve it; report the reason. throw new \RuntimeException($result->rejectionReason);}
if ($result->hadThreats()) { // The disarmed bytes are safe to render. Each removed threat carries its // type and object number for your audit log — never silently. foreach ($result->removedThreats as $threat) { error_log(\sprintf( 'CDR removed %s in object %d', $threat->type->value, $threat->objectNumber, )); }}
$cleanBytes = $result->sanitizedPdf; // The security projection. Not the original.Nie ma ścieżki, na której ten kod po cichu oddaje wciąż niebezpieczny plik. Albo
dokument jest dopuszczony i rozbrojony, albo jest odrzucony z podaną przyczyną.
Lista removedThreats oznacza, że rozbrojenie da się audytować, a nie że jest
magiczne.
Częste nieporozumienie
Dział zatytułowany „Częste nieporozumienie”„CDR to po prostu redakcja z dodatkowymi krokami.”
Nie jest, a mylenie tych dwóch jest niebezpieczne. Redakcja usuwa informację — nazwiska, numery kont, treść, której człowiek nie może zobaczyć. CDR usuwa zdolność — JavaScript, akcję Launch, osadzony ładunek, którego maszyna nie może uruchomić. Mają przeciwne kryteria sukcesu. Redakcja jest poprawna, gdy wrażliwa treść zniknęła, a reszta jest zachowana dosłownie. Rozbrojenie jest poprawne, gdy zagrożenie zniknęło, i jest doskonale skłonne zmienić nieszkodliwą strukturę, by to osiągnąć. Użyj narzędzia, które pasuje do twojej intencji; nie sięgaj po jedno, oczekując gwarancji drugiego.
Drugie nieporozumienie jest takie, że czysta odbudowa dowodzi, iż oryginał był czysty. Nie dowodzi niczego o oryginale. Dowodzi jedynie, że wyjście nie zawiera wykrytego zagrożenia. Dane wejściowe mogły być bronią; zadaniem CDR jest upewnić się, że to, co przekazujesz dalej, nią nie jest.
Ograniczenia i granice
Dział zatytułowany „Ograniczenia i granice”To część, którą broszury pomijają, więc powiemy ją wprost.
- Wyjście to projekcja bezpieczeństwa, a nie kopia dowodowa. Źródło
CdrEngineniesie to jako architektoniczną czerwoną linię. Zsanityzowany PDF nie może być użyty do prawnego zabezpieczenia dowodów, do porównania skrótu z oryginałem ani jako kopia archiwalna. Transformacja jest destrukcyjna i nieodwracalna z założenia. - Wykrywanie ma zakres. CDR usuwa zagrożenia, które potrafi nazwać. To silna, audytowalna warstwa w stosie obrony w głąb — a nie gwarancja, że plik jest wolny od każdej możliwej przyszłej techniki. Trzymaj ją za tą samą walidacją przesyłania, kontrolą typu treści oraz obsługą o najmniejszych uprawnieniach, które opisują wytyczne OWASP dotyczące przesyłania plików.
- Niektóre polityki są celowo stratne. Włączane opcjonalnie przypadki
Strip*usuwają pliki osadzone, podpisy, pola formularzy, warstwy oraz media 3D. Są potężne i usuną legalną treść — na przykład ładunek faktury ZUGFeRD/Factur-X. Są domyślnie wyłączone dokładnie z tego powodu. Włączaj je świadomie. - Podpisy nie przeżywają odbudowy. Rekonstrukcja pliku zmienia jego bajty, więc każdy oryginalny podpis cyfrowy nie pasuje już do swojego zakresu bajtów. Rozbrojony dokument jest niepodpisany względem źródła. Jeśli potrzebujesz podpisanego artefaktu, podpisz czyste wyjście jako nową czynność.
| Edition | Availability |
|---|---|
| Core | Not available. NextPDF core does not perform CDR. It parses, renders, and writes PDFs; it does not threat-detect or rebuild untrusted input. |
| Pro | Not available in the Pro edition. |
| Enterprise | Available via |
Powiązane dokumenty
Dział zatytułowany „Powiązane dokumenty”- Jak naprawdę działa szyfrowanie PDF — druga połowa obsługi wrażliwych plików PDF: ochrona treści kontra usuwanie zdolności.
- Błędy jako funkcja — filozofia
zawodzenia bezpiecznie, którą ucieleśniają odrzucenia kontroli dopuszczenia CDR
oraz zabezpieczenie
/Root. - API, które odmawia zgadywania — dlaczego typ wyniku rozróżniający oczyszczone od odrzuconego bije po cichu wykonaną najlepszą próbę.
Słownik pojęć
Dział zatytułowany „Słownik pojęć”- CDR (Content Disarm & Reconstruction) — strategia sanityzacji, która parsuje niezaufany plik, usuwa aktywne lub niebezpieczne komponenty i odbudowuje czysty plik z bezpiecznej reszty, zamiast skanować w poszukiwaniu znanych-złych sygnatur.
- Projekcja bezpieczeństwa — zsanityzowane wyjście, które zachowuje wystarczająco dużo ze źródła, by było użyteczne, gwarantując jednocześnie usunięcie zagrożeń. Jest celowo niewierne bajtowo i nieodpowiednie do dowodów, haszowania ani archiwizacji.
- Kontrola dopuszczenia — brama przedsanityzacyjna, która odrzuca dokumenty przekraczające limity zasobów (liczba obiektów, liczba stron, rozmiar zdekodowanego strumienia, współczynnik inflacji), zanim rozpocznie się jakakolwiek praca rozbrajania.
- Akcja — konstrukcja PDF, która sprawia, że coś się dzieje na wyzwalacz taki jak otwarcie dokumentu lub zmiana pola; katalog typów akcji (Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4) obejmuje akcje JavaScript i Launch, kanoniczną powierzchnię zagrożeń CDR.
- Wiszące odwołanie — wskaźnik do obiektu, który po filtrowaniu już nie istnieje. Faza czyszczenia odwołań usuwa je, dzięki czemu odbudowany plik pozostaje strukturalnie spójny.