Przejdź do głównej zawartości
getnextpdf.com

Enterprise edycja

Content Disarm and Reconstruction — szczegółowa referencja

Ta strona to dogłębna dokumentacja modułu NextPDF\Enterprise\Security\Cdr. Moduł rozbraja niezaufany plik PDF i odtwarza czysty plik na podstawie jego bezpiecznych obiektów. Potok obejmuje: parsowanie, kontrolę dopuszczania, wykrywanie zagrożeń, filtrowanie, czyszczenie odwołań i odbudowę. Wynik jest projekcją bezpieczeństwa danych wejściowych, nigdy kopią dowodową. Wskazówki dotyczące przepływu pracy znajdziesz najpierw na stronie funkcji CDR.

Ta funkcja jest dostarczana w NextPDF Enterprise (nextpdf/enterprise) i aktywuje się wraz z kopertą licencyjną poziomu Enterprise. Wdrożenie bez tego uprawnienia nie ładuje klas tej funkcji. Porównaj edycje i uzyskaj licencję.

SymbolParametryDomyślne zachowanieZwracaZgłasza lub kończy się błędemUwagi
CdrEngine::__constructbrakTworzy wewnętrzny detektor i moduł odbudowyCdrEngineNic nie zadeklarowanoBrak wstrzykiwalnych współpracowników
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullUruchamia pełny potok pod CdrPolicy::standard()CdrResultNie zgłasza wyjątku dla wrogich danych wejściowych; niepowodzenia parsowania i dopuszczania zwracają odrzucony wynikWynik raportuje odrzucenie odrębnie od sanityzacji
CdrPolicy::__constructsiedem opcjonalnych parametrów nazwanych, patrz blok koduPusty zestaw usuwania; allowUriActions false; flattenIncrementalUpdates true; limity 100000 obiektów, 256 MiB po dekodowaniu, 10000 stron, 1000.0 współczynnika inflacjiCdrPolicyNic nie zadeklarowanofinal readonly; pusta lista removeThreatTypes niczego nie wykrywa
CdrPolicy::standardbrakStarszy zestaw zagrożeń; akcje URI usuwane; domyślne limityselfNic nie zadeklarowanoWyklucza siedem stratnych przypadków Strip*
CdrPolicy::paranoidbrakStarszy zestaw zagrożeń z zaostrzonymi limitami: 50000 obiektów, 128 MiB, 5000 stron, 100.0 współczynnika inflacjiselfNic nie zadeklarowanoWyklucza siedem stratnych przypadków Strip*
CdrPolicy::permissivebrakUsuwa tylko JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; zachowuje akcje URIselfNic nie zadeklarowanoPrzeznaczone dla zaufanych źródeł
CdrPolicy::allThreatTypesbrakZwraca każdy przypadek ThreatType, w tym stratne przypadki Strip*list<ThreatType>Nic nie zadeklarowanoJawna zgoda na maksymalne usuwanie
CdrPolicy::legacyThreatTypesbrakZwraca każdy przypadek z wyjątkiem siedmiu przypadków Strip*list<ThreatType>Nic nie zadeklarowanoDomyślny zestaw usuwania dla standard() i paranoid()
CdrPolicy::shouldRemoveThreatType $typeTest przynależności do removeThreatTypesboolNic nie zadeklarowanoZwraca false dla UriAction, gdy allowUriActions ma wartość true
ThreatDetector::detectPdfReader $reader, CdrPolicy $policySkanuje każdy obiekt oraz katalog trailera pod kątem typów zagrożeń z politykilist<DetectedThreat>Nie zgłasza wyjątku; obiekt niemożliwy do sparsowania staje się zagrożeniem UnparseableObjectSkan katalogu obejmuje drzewo /Names/JavaScript
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policySerializuje bezpieczne obiekty do jednorewizyjnego pliku %PDF-2.0stringNic nie zadeklarowano; obiekty, które nie przejdą ponownego odczytu lub walidacji /Length, są pomijane$policy jest zarezerwowany na przyszłe modyfikacje serializacji
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''Niemutowalny obiekt wartości opisujący wykrycieDetectedThreatNic nie zadeklarowanoWszystkie cztery właściwości są public readonly
ThreatTypeenum oparty na łańcuchach znakówDwadzieścia przypadków: trzynaście starszych plus siedem opcjonalnych przypadków Strip*n/an/aPatrz inwentarz przypadków poniżej
final class CdrEngine
{
public function __construct()
public function sanitize(string $pdfData, ?CdrPolicy $policy = null): CdrResult
}
final readonly class CdrPolicy
{
public function __construct(
public array $removeThreatTypes = [],
public bool $allowUriActions = false,
public bool $flattenIncrementalUpdates = true,
public int $maxObjects = 100_000,
public int $maxDecodedStreamBytes = 268_435_456,
public int $maxPageCount = 10_000,
public float $maxInflationRatio = 1000.0,
)
public static function standard(): self
public static function paranoid(): self
public static function permissive(): self
public static function allThreatTypes(): array
public static function legacyThreatTypes(): array
public function shouldRemove(ThreatType $type): bool
}
final class ThreatDetector
{
public function detect(PdfReader $reader, CdrPolicy $policy): array
}
final class CdrRebuilder
{
public function rebuild(PdfReader $reader, array $safeObjNums, array $removedObjNums, CdrPolicy $policy): string
}
final readonly class DetectedThreat
{
public function __construct(
public ThreatType $type,
public int $objectNumber,
public string $description,
public string $location = '',
)
}
enum ThreatType: string

Trzynaście starszych przypadków tworzy domyślny zestaw usuwania. Przypadki Strip* są z założenia stratne i nigdy nie trafiają do domyślnej polityki.

PrzypadekWartość bazowaPowierzchnia wykrywania
ThreatType::JavaScriptjavascriptklucz /JS na dowolnym obiekcie lub akcja /S /JavaScript
ThreatType::AdditionalActionsadditional-actionssłownik /AA na dowolnym obiekcie
ThreatType::OpenActionopen-actionklucz /OpenAction na dowolnym obiekcie
ThreatType::LaunchActionlaunch-actionakcja /S /Launch
ThreatType::RemoteGoToremote-gotoakcja /S /GoToR lub /S /GoToE
ThreatType::SubmitFormsubmit-formakcja /S /SubmitForm
ThreatType::ImportDataimport-dataakcja /S /ImportData
ThreatType::EmbeddedFilesembedded-filesdrzewo nazw /EmbeddedFiles lub słownik /EF
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptdrzewo nazw /Names/JavaScript w katalogu
ThreatType::UriActionuri-actionakcja /S /URI; pomijana, gdy allowUriActions ma wartość true
ThreatType::Xfaxfaklucz /XFA
ThreatType::UnparseableObjectunparseable-objectdowolny obiekt lub katalog, którego nie da się sparsować
ThreatType::StripJavaScriptstrip-javascriptOpcjonalny nadzbiór: klucz /JS, /S /JavaScript lub /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesOpcjonalnie: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles lub /EF
ThreatType::StripFormFieldsstrip-form-fieldsOpcjonalnie: /Subtype /Widget, klucz /FT lub klucz /AcroForm
ThreatType::StripAnnotationsRichstrip-annotations-richOpcjonalne podtypy: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultOpcjonalnie: /Type /OCG z kluczem /Usage lub /Visibility
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildOpcjonalnie: /Type /Sig, /FT /Sig, /DSS, /VRI lub /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaOpcjonalne podtypy: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize wykonuje sześć uporządkowanych faz i nigdy nie zgłasza wyjątku dla wrogich danych wejściowych.

  1. Parsowanie. Niepowodzenie parsowania zwraca wynik z admitted false oraz powodem odrzucenia w postaci błędu parsowania. Zsanityzowane dane wyjściowe są w takim przypadku puste.
  2. Kontrola dopuszczania. Liczba obiektów, łączna liczba bajtów strumieni po dekodowaniu, współczynnik inflacji na strumień oraz liczba stron są sprawdzane względem limitów polityki. Dokument przekraczający limit jest odrzucany, a nie sanityzowany. Odrzucenie i sanityzacja są raportowane odrębnie.
  3. Wykrywanie. ThreatDetector::detect skanuje każdy obiekt oraz katalog trailera pod kątem typów zagrożeń z polityki. Obiekty niemożliwe do sparsowania są rejestrowane jako wykrycia ThreatType::UnparseableObject, a nie pomijane.
  4. Filtrowanie. Obiekty niosące wykrycia są kolejkowane do usunięcia. Katalog dokumentu nigdy nie jest usuwany jako cały obiekt. Wykrycia na poziomie katalogu (OpenAction, AdditionalActions, NamedJavaScript) są zamiast tego naprawiane przez usunięcie kluczy.
  5. Czyszczenie odwołań. Każde pośrednie odwołanie do usuniętego obiektu jest zastępowane wartością null podczas serializacji.
  6. Odbudowa. CdrRebuilder::rebuild generuje jednorewizyjny plik %PDF-2.0 z przenumerowanymi obiektami, klasyczną tablicą odwołań krzyżowych i świeżym trailerem. Bezpieczne bajty strumieni są kopiowane bajt w bajt. Odbudowany katalog usuwa /OpenAction, /AA oraz /Names; /AA jest usuwany z każdego obiektu.

Zwracany CdrResult udostępnia odbudowane bajty, listę usuniętych zagrożeń, oba rozmiary w bajtach, flagę dopuszczenia oraz powód odrzucenia. Jeśli źródło miało rozstrzygalny /Root, a odbudowane dane wyjściowe go utraciły, silnik odrzuca dane wyjściowe zamiast zwracać strukturalnie uszkodzony plik. Jest to gwarancja fail-closed: admitted true oznacza, że dane wyjściowe nadal niosą odwołanie do katalogu dokumentu.

Aktualizacje przyrostowe nigdy nie przetrwają: odbudowa serializuje dokładnie jedną rewizję w każdej polityce, więc późne rewizje typu shadow są spłaszczane z założenia. Oryginalne podpisy cyfrowe nie mogą pozostać ważne po odbudowie, ponieważ zakresy bajtów nie odpowiadają już danym wyjściowym.

Architektoniczna czerwona linia. CDR to warstwa projekcji bezpieczeństwa, a nie warstwa zachowywania. Dane wyjściowe nie mogą być używane do zachowywania dowodów prawnych, porównywania skrótów z oryginałem ani do kopii archiwalnych.

  • Polityka null rozwiązywana jest do CdrPolicy::standard(). Polityka utworzona z domyślną pustą removeThreatTypes niczego nie wykrywa ani nie usuwa.
  • allowUriActions ustawione na true pomija usuwanie UriAction, nawet gdy przypadek ten jest obecny w removeThreatTypes.
  • flattenIncrementalUpdates jest w tym wydaniu deklaratywne: odbudowa generuje pojedynczą rewizję w każdej polityce, w tym permissive(), która ustawia tę flagę na false.
  • Kontrola współczynnika inflacji traktuje surową długość strumienia równą zero jak jeden, więc strumień rozprężający się z niczego jest nadal ograniczony. Gdy nie jest zachowywana żadna forma zdekodowana, surowa długość strumienia wlicza się do łącznego budżetu.
  • Kontrola dopuszczania oparta na liczbie stron działa w trybie best-effort: niepowodzenie odczytu katalogu lub drzewa stron samo w sobie nie odrzuca dokumentu. Budżety liczby obiektów i dekompresji są zawsze egzekwowane.
  • Obiekt, którego surowa długość strumienia nie zgadza się z jego całkowitoliczbowym wpisem /Length, jest pomijany podczas odbudowy (obrona przed plikami polyglot). Odwołanie do takiego pominiętego obiektu zachowuje swój źródłowy numer obiektu i może nie zostać rozstrzygnięte w danych wyjściowych. sanitize() odrzuca wykrywalnie uszkodzone wyniki (brakujący /Root), ale wywołujący, który bezpośrednio steruje niskopoziomowym CdrRebuilder::rebuild(), musi sam ponownie zweryfikować strukturę wyjścia i integralność odwołań.
  • Gdy źródłowy trailer niesie /ID, odbudowany trailer niesie świeżo wygenerowany losowy /ID, a nie oryginalny. Pozostałe wpisy trailera, w tym /Info, nie są przenoszone; odbudowany trailer zawiera /Size, /Root gdy jest rozstrzygalny, oraz zregenerowany /ID.
  • Zdekodowane bajty nazw i kluczy są ponownie emitowane z szesnastkowymi sekwencjami ucieczki dla ograniczników, białych znaków i bajtów niedrukowalnych, więc wrogie nazwy nie mogą wstrzyknąć składni słownika do danych wyjściowych.
  • Wartości łańcuchowe pod kluczami słownika spoza znanego zbioru kluczy o wartościach nazwowych są zachowawczo emitowane jako łańcuchy literalne.
  • CdrPolicy::legacyThreatTypes() traktuje każdy przyszły przypadek enum jako domyślnie usuwany, o ile nie jest zarejestrowany jako przypadek Strip*, więc nowe stratne przypadki nie mogą po cichu trafić do domyślnych polityk.
  • CDR nie jest modułem kryptograficznym. Jedynym użyciem losowości jest zregenerowany /ID trailera. Walidacja podpisu jest tutaj poza zakresem; zobacz dogłębną dokumentację podpisów.
TwierdzenieStandardKlauzula
Wywołanie akcji ECMAScript powoduje, że procesor PDF wykonuje osadzony skrypt.ISO 32000-2§12.6.4.17
Wszystkie skrypty na poziomie dokumentu w drzewie nazw JavaScript wykonują się przy otwarciu dokumentu.ISO 32000-2§12.6.4.17
Słownik nazw katalogu może zawierać drzewo nazw JavaScript z akcjami skryptowymi na poziomie dokumentu.ISO 32000-2§7.7.4 (Table 32)
Akcja launch uruchamia aplikację albo otwiera lub drukuje dokument.ISO 32000-2§12.6.4.6
Słowniki dodatkowych akcji /AA rozszerzają zdarzenia wyzwalające na adnotacjach, stronach, polach i katalogu.ISO 32000-2§12.6.3
Przyjmowanie niezaufanych plików musi ograniczać obecność, objętość i zawartość napływających plików.OWASP ASVS 5.0§5.2
Systemy powinny zapobiegać niewłaściwemu wykonywaniu przesyłanych plików i wykrywać niebezpieczną zawartość.OWASP ASVS 5.0§5.3

Wszystkie klauzule są parafrazowane; NextPDF nie odtwarza tekstu normatywnego. NextPDF nie formułuje żadnego twierdzenia o certyfikacji. CDR usuwa powierzchnie aktywnej zawartości wyliczone przez ThreatType zgodnie ze skonfigurowaną polityką; jest to funkcja, a nie certyfikowany sanityzator. CDR nie jest skanerem antywirusowym i nie wykrywa sygnatur złośliwego oprogramowania; uzupełnia, ale nie spełnia, kontroli takich jak skanowanie antywirusowe OWASP ASVS 5.4.3. To, czy rozbrojony plik jest akceptowalny dla danego potoku przyjmowania, pozostaje decyzją o ryzyku po stronie operatora.

  • Źródło modułu nosi @since 1.9.0; niniejsza dokumentacja opisuje powierzchnię w postaci dostarczonej w nextpdf/enterprise 3.1.0.
  • Wszystko działa w procesie na Twoim hoście. Podczas sanityzacji nie następuje żaden dostęp do sieci.
  • CdrPolicy i DetectedThreatfinal readonly; aby zmienić limity, utwórz nową instancję polityki.
  • CdrEngine tworzy swój detektor i moduł odbudowy wewnętrznie. ThreatDetector i CdrRebuilder pozostają bezpośrednio używalne w wieloetapowych potokach, które dostarczają własny PdfReader.
  • Parametr $policy metody CdrRebuilder::rebuild jest obecnie zarezerwowany; źródło dokumentuje go jako zachowany dla zgodności miejsc wywołania i przyszłych modyfikacji serializacji zależnych od polityki.
  • Dane wyjściowe są odtwarzalne strukturalnie, a nie bitowo: zregenerowany /ID różni się przy każdym uruchomieniu, gdy źródło go zawierało.
  • Typ wyniku CdrResult (wartość zwracana przez sanitize()) został omówiony behawioralnie powyżej; jego pola są public readonly, a hadThreats() i threatCount() są udogodnieniami.

Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie i wspieraną publiczną powierzchnię API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tablice mechanizmów, nazwy plików runbooków i prefiksy zgłoszeń są poza zakresem.