Zum Inhalt springen
getnextpdf.com

Enterprise Edition

Content Disarm and Reconstruction — Ausführliche Referenz

Diese Seite ist die Deep-Reference für das Modul NextPDF\Enterprise\Security\Cdr. Das Modul entwaffnet ein nicht vertrauenswürdiges PDF und rekonstruiert aus dessen sicheren Objekten eine saubere Datei. Die Pipeline lautet: Parsen, Zugangskontrolle, Bedrohungserkennung, Filterung, Referenzbereinigung, Rebuild. Die Ausgabe ist eine Sicherheitsprojektion der Eingabe, niemals eine beweiskräftige Kopie. Zur Orientierung im Arbeitsablauf lesen Sie zuerst die CDR-Funktionsseite.

Diese Funktion wird in NextPDF Enterprise (nextpdf/enterprise) ausgeliefert und aktiviert sich mit einer Lizenzhülle der Enterprise-Stufe. Eine Bereitstellung ohne diese Berechtigung lädt die Klassen der Funktion nicht. Editionen vergleichen und Lizenz erwerben.

SymbolParameterStandardverhaltenRückgabeWirft oder scheitert mitHinweise
CdrEngine::__constructkeineKonstruiert den internen Detector und RebuilderCdrEngineNichts deklariertKeine injizierbaren Kollaborateure
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullFührt die vollständige Pipeline unter CdrPolicy::standard() ausCdrResultWirft bei feindlicher Eingabe nicht; Parse- und Zugangsfehler geben ein abgelehntes Ergebnis zurückDas Ergebnis meldet Ablehnung getrennt von der Sanitisierung
CdrPolicy::__constructsieben optionale benannte Parameter, siehe FenceLeere Entfernungsmenge; allowUriActions false; flattenIncrementalUpdates true; Limits 100000 Objekte, 256 MiB dekodiert, 10000 Seiten, 1000.0 InflationCdrPolicyNichts deklariertfinal readonly; eine leere removeThreatTypes-Liste erkennt nichts
CdrPolicy::standardkeineLegacy-Bedrohungsmenge; URI-Aktionen entfernt; StandardlimitsselfNichts deklariertSchließt die sieben verlustbehafteten Strip*-Fälle aus
CdrPolicy::paranoidkeineLegacy-Bedrohungsmenge mit strengeren Limits: 50000 Objekte, 128 MiB, 5000 Seiten, 100.0 InflationselfNichts deklariertSchließt die sieben verlustbehafteten Strip*-Fälle aus
CdrPolicy::permissivekeineEntfernt nur JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; erhält URI-AktionenselfNichts deklariertFür vertrauenswürdige Quellen gedacht
CdrPolicy::allThreatTypeskeineGibt jeden ThreatType-Fall zurück, einschließlich der verlustbehafteten Strip*-Fällelist<ThreatType>Nichts deklariertDer explizite Opt-in für maximales Strippen
CdrPolicy::legacyThreatTypeskeineGibt jeden Fall außer den sieben Strip*-Fällen zurücklist<ThreatType>Nichts deklariertStandard-Entfernungsmenge für standard() und paranoid()
CdrPolicy::shouldRemoveThreatType $typeZugehörigkeitsprüfung gegen removeThreatTypesboolNichts deklariertGibt false für UriAction zurück, wenn allowUriActions true ist
ThreatDetector::detectPdfReader $reader, CdrPolicy $policyScannt jedes Objekt und den Trailer-Katalog auf die Bedrohungstypen der Richtlinielist<DetectedThreat>Wirft nicht; ein nicht parsebares Objekt wird zu einer UnparseableObject-BedrohungDer Katalog-Scan deckt den /Names/JavaScript-Baum ab
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policySerialisiert sichere Objekte in eine %PDF-2.0-Datei mit einer einzigen RevisionstringNichts deklariert; Objekte, die beim erneuten Lesen oder bei der /Length-Validierung scheitern, werden übersprungen$policy ist für künftige Serialisierungsanpassungen reserviert
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''Unveränderliches Befund-WertobjektDetectedThreatNichts deklariertAlle vier Eigenschaften sind public readonly
ThreatTypestring-backed enumZwanzig Fälle: dreizehn Legacy plus sieben Opt-in-Strip*-Fällen/vn/vSiehe die Fallübersicht unten
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

Dreizehn Legacy-Fälle bilden die Standard-Entfernungsmenge. Die Strip*-Fälle sind konstruktionsbedingt verlustbehaftet und gelangen niemals in eine Standardrichtlinie.

FallHinterlegter WertErkennungsoberfläche
ThreatType::JavaScriptjavascript/JS-Schlüssel auf einem beliebigen Objekt oder eine /S /JavaScript-Aktion
ThreatType::AdditionalActionsadditional-actions/AA-Wörterbuch auf einem beliebigen Objekt
ThreatType::OpenActionopen-action/OpenAction-Schlüssel auf einem beliebigen Objekt
ThreatType::LaunchActionlaunch-action/S /Launch-Aktion
ThreatType::RemoteGoToremote-goto/S /GoToR- oder /S /GoToE-Aktion
ThreatType::SubmitFormsubmit-form/S /SubmitForm-Aktion
ThreatType::ImportDataimport-data/S /ImportData-Aktion
ThreatType::EmbeddedFilesembedded-files/EmbeddedFiles-Namensbaum oder /EF-Wörterbuch
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptKatalog-/Names/JavaScript-Namensbaum
ThreatType::UriActionuri-action/S /URI-Aktion; unterdrückt, wenn allowUriActions true ist
ThreatType::Xfaxfa/XFA-Schlüssel
ThreatType::UnparseableObjectunparseable-objectJedes Objekt oder jeder Katalog, der beim Parsen scheitert
ThreatType::StripJavaScriptstrip-javascriptOpt-in-Obermenge: /JS-Schlüssel, /S /JavaScript oder /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesOpt-in: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles oder /EF
ThreatType::StripFormFieldsstrip-form-fieldsOpt-in: /Subtype /Widget, /FT-Schlüssel oder /AcroForm-Schlüssel
ThreatType::StripAnnotationsRichstrip-annotations-richOpt-in-Subtypen: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultOpt-in: /Type /OCG mit einem /Usage- oder /Visibility-Schlüssel
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildOpt-in: /Type /Sig, /FT /Sig, /DSS, /VRI oder /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaOpt-in-Subtypen: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize führt sechs geordnete Phasen aus und wirft bei feindlicher Eingabe niemals.

  1. Parsen. Ein Parse-Fehler gibt ein Ergebnis mit admitted false und einem Parse-Fehler-Ablehnungsgrund zurück. Die sanitisierte Ausgabe ist in diesem Fall leer.
  2. Zugangskontrolle. Die Objektanzahl, die aggregierten dekodierten Stream-Bytes, das Inflationsverhältnis pro Stream und die Seitenanzahl werden gegen die Richtlinienlimits geprüft. Ein überlimitiertes Dokument wird abgelehnt, nicht sanitisiert. Ablehnung und Sanitisierung werden getrennt gemeldet.
  3. Erkennung. ThreatDetector::detect scannt jedes Objekt und den Trailer-Katalog auf die Bedrohungstypen der Richtlinie. Nicht parsebare Objekte werden als ThreatType::UnparseableObject-Befunde erfasst, anstatt übersprungen zu werden.
  4. Filterung. Objekte, die Befunde tragen, werden zur Entfernung in die Warteschlange gestellt. Der Dokumentkatalog wird niemals als Gesamtobjekt entfernt. Befunde auf Katalogebene (OpenAction, AdditionalActions, NamedJavaScript) werden stattdessen durch Schlüsselentfernung behoben.
  5. Referenzbereinigung. Jede indirekte Referenz auf ein entferntes Objekt wird während der Serialisierung durch null ersetzt.
  6. Rebuild. CdrRebuilder::rebuild gibt eine %PDF-2.0-Datei mit einer einzigen Revision aus, mit neu nummerierten Objekten, einer klassischen Querverweistabelle und einem frischen Trailer. Sichere Stream-Bytes werden byte-identisch kopiert. Der neu aufgebaute Katalog verwirft /OpenAction, /AA und /Names; /AA wird aus jedem Objekt entfernt.

Das zurückgegebene CdrResult legt die neu aufgebauten Bytes, die Liste der entfernten Bedrohungen, beide Byte-Größen, das Zugangs-Flag und den Ablehnungsgrund offen. Hatte die Quelle einen auflösbaren /Root und die neu aufgebaute Ausgabe verlor ihn, lehnt die Engine die Ausgabe ab, anstatt eine strukturell defekte Datei zurückzugeben. Dies ist eine fail-closed-Garantie: admitted true impliziert, dass die Ausgabe noch eine Dokumentkatalog-Referenz trägt.

Inkrementelle Aktualisierungen überleben niemals: Der Rebuild serialisiert unter jeder Richtlinie genau eine Revision, sodass Shadow-artige späte Revisionen konstruktionsbedingt abgeflacht werden. Ursprüngliche digitale Signaturen können über einen Rebuild hinweg nicht gültig bleiben, weil die Byte-Bereiche nicht mehr zur Ausgabe passen.

Architektonische rote Linie. CDR ist eine Sicherheitsprojektionsschicht, keine Erhaltungsschicht. Die Ausgabe darf nicht für die rechtliche Beweissicherung, den Hash-Vergleich mit dem Original oder für Archivkopien verwendet werden.

  • Eine null-Richtlinie wird zu CdrPolicy::standard() aufgelöst. Eine Richtlinie, die mit dem standardmäßig leeren removeThreatTypes konstruiert wurde, erkennt und entfernt nichts.
  • allowUriActions auf true gesetzt unterdrückt die UriAction-Entfernung, selbst wenn der Fall in removeThreatTypes vorhanden ist.
  • flattenIncrementalUpdates ist in diesem Release deklarativ: Der Rebuild gibt unter jeder Richtlinie eine einzige Revision aus, einschließlich permissive(), das das Flag auf false setzt.
  • Die Inflationsverhältnisprüfung behandelt eine rohe Stream-Länge von null als eins, sodass ein Stream, der aus dem Nichts inflationiert, weiterhin begrenzt ist. Wenn keine dekodierte Form beibehalten wird, zählt die rohe Stream-Länge zum aggregierten Budget.
  • Die Seitenzahl-Zugangsprüfung ist Best-Effort: Ein Lesefehler des Katalogs oder des Seitenbaums lehnt das Dokument nicht von sich aus ab. Die Objektzahl- und Dekompressionsbudgets werden immer erzwungen.
  • Ein Objekt, dessen rohe Stream-Länge nicht mit seinem ganzzahligen /Length-Eintrag übereinstimmt, wird zum Rebuild-Zeitpunkt übersprungen (Polyglot-Abwehr). Eine Referenz auf ein solches übersprungenes Objekt behält seine Quell-Objektnummer und lässt sich in der Ausgabe möglicherweise nicht auflösen. sanitize() verweigert erkennbar defekte Ergebnisse (ein fehlendes /Root), aber ein Aufrufer, der das Low-Level-CdrRebuilder::rebuild() direkt ansteuert, muss die Ausgabestruktur und die Referenzintegrität selbst erneut validieren.
  • Trägt der Quell-Trailer /ID, so trägt der neu aufgebaute Trailer ein frisch generiertes zufälliges /ID, nicht das ursprüngliche. Andere Trailer-Einträge, einschließlich /Info, werden nicht übernommen; der neu aufgebaute Trailer hält /Size, /Root sofern auflösbar und das regenerierte /ID.
  • Dekodierte Namens- und Schlüsselbytes werden mit hexadezimalen Escapes für Trennzeichen, Whitespace und nicht druckbare Bytes neu ausgegeben, sodass feindliche Namen keine Wörterbuchsyntax in die Ausgabe einschleusen können.
  • Zeichenkettenwerte unter Wörterbuchschlüsseln außerhalb der bekannten namenswertigen Menge werden konservativ als literale Zeichenketten ausgegeben.
  • CdrPolicy::legacyThreatTypes() behandelt jeden künftigen Enum-Fall als standardmäßig entfernt, sofern er nicht als Strip*-Fall registriert ist, sodass neue verlustbehaftete Fälle nicht stillschweigend in Standardrichtlinien gelangen können.
  • CDR ist kein kryptografisches Modul. Seine einzige Nutzung von Zufälligkeit ist das regenerierte Trailer-/ID. Die Signaturvalidierung liegt hier außerhalb des Geltungsbereichs; siehe die Signatur-Deep-Reference.
BehauptungStandardKlausel
Das Aufrufen einer ECMAScript-Aktion veranlasst einen PDF-Prozessor, das eingebettete Skript auszuführen.ISO 32000-2§12.6.4.17
Dokumentweite Skripte im JavaScript-Namensbaum werden alle ausgeführt, wenn das Dokument geöffnet wird.ISO 32000-2§12.6.4.17
Das Katalog-Namenswörterbuch kann einen JavaScript-Namensbaum mit dokumentweiten Skriptaktionen halten.ISO 32000-2§7.7.4 (Table 32)
Eine Launch-Aktion startet eine Anwendung oder öffnet oder druckt ein Dokument.ISO 32000-2§12.6.4.6
/AA-Additional-Actions-Wörterbücher erweitern die Auslöseereignisse auf Annotationen, Seiten, Feldern und dem Katalog.ISO 32000-2§12.6.3
Die Aufnahme nicht vertrauenswürdiger Dateien muss Vorhandensein, Volumen und Inhalt eingehender Dateien begrenzen.OWASP ASVS 5.0§5.2
Systeme sollten die unangemessene Ausführung hochgeladener Dateien verhindern und gefährlichen Inhalt erkennen.OWASP ASVS 5.0§5.3

Alle Klauseln sind paraphrasiert; NextPDF reproduziert keinen normativen Text. NextPDF erhebt keinen Zertifizierungsanspruch. CDR entfernt die durch ThreatType aufgezählten Aktivinhalt-Oberflächen unter der konfigurierten Richtlinie; es ist eine Fähigkeit, kein zertifizierter Sanitizer. CDR ist kein Antivirus-Scanner und erkennt keine Malware-Signaturen; es ergänzt Kontrollen wie das Antivirus-Scanning nach OWASP ASVS 5.4.3 und erfüllt sie nicht. Ob eine entwaffnete Datei für eine gegebene Aufnahme-Pipeline akzeptabel ist, bleibt die Risikoentscheidung des Betreibers.

  • Der Modulquellcode trägt @since 1.9.0; diese Reference dokumentiert die Oberfläche, wie sie in nextpdf/enterprise 3.1.0 ausgeliefert wird.
  • Alles läuft in-process auf Ihrem Host. Während der Sanitisierung findet kein Netzwerkzugriff statt.
  • CdrPolicy und DetectedThreat sind final readonly; konstruieren Sie eine neue Richtlinieninstanz, um Limits zu ändern.
  • CdrEngine konstruiert seinen Detector und Rebuilder intern. ThreatDetector und CdrRebuilder bleiben für gestufte Pipelines, die ihren eigenen PdfReader bereitstellen, direkt nutzbar.
  • Der $policy-Parameter von CdrRebuilder::rebuild ist gegenwärtig reserviert; der Quellcode dokumentiert ihn als beibehalten zur Aufrufstellen-Kompatibilität und für künftige richtlinienspezifische Serialisierungsanpassungen.
  • Die Ausgabe ist strukturell reproduzierbar, nicht bitweise reproduzierbar: Das regenerierte /ID unterscheidet sich bei jedem Lauf, wenn die Quelle eines trug.
  • Der Ergebnistyp CdrResult (Rückgabewert von sanitize()) ist oben verhaltensmäßig abgedeckt; seine Felder sind public readonly, mit hadThreats() und threatCount() als Bequemlichkeiten.

Diese Seite dokumentiert ausschließlich extern beobachtbares Verhalten und die unterstützte öffentliche API-Oberfläche. Interne Namespace-Pfade, Hilfsklassen, Mechanismustabellen, Runbook-Dateinamen und Ticket-Präfixe liegen außerhalb des Geltungsbereichs.