Nicht vertrauenswürdige PDFs bereinigen: Content Disarm and Reconstruction
Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4
Auf einen Blick
Abschnitt betitelt „Auf einen Blick“Ein PDF, das aus der Außenwelt eintrifft, ist ebenso sehr Code wie es ein Dokument ist. Es kann JavaScript, eine Launch-Aktion, eine eingebettete ausführbare Datei und eine Struktur tragen, die darauf ausgelegt ist, einen Parser zu Fall zu bringen. Content Disarm & Reconstruction (CDR) behandelt diese Datei als nicht vertrauenswürdig, behält nur, was sicher ist, und baut aus den Überlebenden ein sauberes PDF neu auf.
Diese Seite erklärt, wie die CdrEngine von NextPDF Enterprise das tut – und das eine
ehrliche Ding, das jeder CDR-Anbieter laut aussprechen sollte: Die neu aufgebaute Datei
ist eine Sicherheitsprojektion des Originals, keine getreue Kopie davon.
Warum das wichtig ist
Abschnitt betitelt „Warum das wichtig ist“Die gefährlichen Teile eines PDF sind nicht exotisch. Sie sind Standardfunktionen. Die Spezifikation definiert einen ganzen Katalog von Aktionen – was passiert, wenn ein Dokument geöffnet wird, wenn eine Seite angezeigt wird, wenn sich ein Feld ändert –, und dieser Katalog umfasst JavaScript- und Launch-Aktionen (Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4). Ein Reader, der das Format respektiert, wird sie bereitwillig ausführen. Das ist der Standfuß des Angreifers: eine Datei, die zugleich vollkommen gültig und vollkommen bösartig ist.
Das Filtern nach Dateierweiterung bewirkt hier nichts. Die Bedrohung steckt in einem wohlgeformten PDF, also ist die einzige echte Verteidigung, es zu öffnen, es zu verstehen und die aktive Maschinerie zu entfernen, bevor sie je einen Renderer erreicht. Dies ist die Haltung der Eingabevalidierung, die der Leitfaden von OWASP zu Datei-Upload und Eingabevalidierung beschreibt: traue den Bytes nie und ziehe es vor, ein bekanntermaßen gutes Artefakt neu aufzubauen, statt ein feindseliges nach bekanntermaßen schlechten Signaturen zu durchsuchen.
Die Kurzfassung
Abschnitt betitelt „Die Kurzfassung“- CDR nimmt an, dass die Eingabe feindselig ist, und erzeugt eine neue Datei, statt die alte zu flicken.
CdrEngine::sanitize()durchläuft sechs Phasen: parsen, Zulassungskontrolle, Bedrohungserkennung, filtern, Referenz-Schrubben, neu aufbauen.- Es gibt ein
CdrResultzurück, das Ihnen sagt, was entfernt wurde, ob das Dokument überhaupt zugelassen wurde und – falls nicht – warum es abgelehnt wurde. - Die Ausgabe ist eine Sicherheitsprojektion. Sie ist ausdrücklich keine beweistaugliche Kopie, keine Hash-Übereinstimmung und kein Archivartefakt. Das ist ein Vertrag, kein Vorbehalt.
- Dies ist nur Enterprise. Der NextPDF-Core führt kein CDR durch.
Wie NextPDF dabei vorgeht
Abschnitt betitelt „Wie NextPDF dabei vorgeht“Die eigene Dokumentation der Engine formuliert die rote Designlinie in drei Worten:
Security Projection Layer. sanitize() ist eine zerstörende, nicht umkehrbare
Transformation. Sie darf Bytes wegwerfen. Was sie nicht darf, ist vorzutäuschen, dass
das Ergebnis dasselbe Dokument ist.
Die Pipeline ist bewusst geordnet. Jede Phase verengt das Vertrauen, bevor die nächste Phase darauf einwirkt.
- 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.
Zulassung vor Entschärfung. Bevor auch nur eine einzige Bedrohung entfernt wird,
fragt die Engine, ob das Dokument überhaupt der Verarbeitung wert ist. CdrPolicy
trägt die Grenzen – maxObjects, maxPageCount, maxDecodedStreamBytes und ein
maxInflationRatio, das gegen Dekompressionsbomben verteidigt. Ein Dokument, das über
sie hinausschießt, wird abgelehnt, und das CdrResult sagt das mit
admitted: false und einem rejectionReason. Diese Unterscheidung ist tragend: „Wir
haben es bereinigt” und „Wir haben es abgelehnt” sind unterschiedliche Ergebnisse, und
der Ergebnistyp hält sie auseinander, sodass es auch Ihre Fehlerberichterstattung kann.
Bedrohungen werden benannt, nicht geraten. ThreatDetector::detect() ordnet jede
gefährliche Konstruktion einem ThreatType zu – JavaScript, LaunchAction,
OpenAction, AdditionalActions, RemoteGoTo, SubmitForm, ImportData,
EmbeddedFiles, RichMedia, NamedJavaScript und mehr –, jede an eine bestimmte
PDF-Funktion gebunden. Ein Objekt, das sich überhaupt nicht parsen lässt, wird zu seinem
eigenen Bedrohungstyp, UnparseableObject, denn ein Objekt, das der Sanitizer nicht
lesen kann, ist ein Objekt, für das er nicht bürgen kann. Jeder Fund ist ein
DetectedThreat, der die anstößige Objektnummer trägt, sodass die Entfernung präzise
ist.
Entfernung schützt das Dokument, nicht nur die Nutzlast. Manche gefährlichen
Schlüssel liegen am Dokumentkatalog (dem Root) – ein /OpenAction etwa, das beim
Öffnen feuert. Das ganze Root-Objekt zu entfernen, um einen Schlüssel zu töten, würde
den Katalog zerstören und die Datei klammheimlich beschädigen. Die Engine behandelt
diese stattdessen als An-Ort-und-Stelle-Schlüsselentfernungen am Katalog, und als ein
Fail-closed-Schutz weigert sie sich, ein neu aufgebautes Dokument auszugeben, das sein
/Root überhaupt verloren hat. Ein Sanitizer, der eine strukturell beschädigte Datei
erzeugt und dabei Erfolg meldet, ist genau der Fehlermodus, den dieser Schutz
verhindern soll.
Praktisches Beispiel
Abschnitt betitelt „Praktisches Beispiel“Die Form unten ist der echte Einstiegspunkt. Sie übergeben der Engine rohe Bytes und
eine Richtlinie; Sie erhalten ein CdrResult zurück, das ehrlich darüber ist, was
geschehen ist.
<?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.Es gibt keinen Pfad, auf dem dieser Code klammheimlich eine immer noch gefährliche
Datei zurückgibt. Entweder wird das Dokument zugelassen und entschärft, oder es wird
mit einem angegebenen Grund abgelehnt. Die removedThreats-Liste bedeutet, dass die
Entschärfung prüfbar ist, nicht magisch.
Häufiges Missverständnis
Abschnitt betitelt „Häufiges Missverständnis“„CDR ist nur Schwärzung mit zusätzlichen Schritten.”
Das ist es nicht, und die beiden zu vermengen ist gefährlich. Schwärzung entfernt Informationen – Namen, Kontonummern, den Inhalt, den ein Mensch nicht sehen darf. CDR entfernt Fähigkeit – das JavaScript, die Launch-Aktion, die eingebettete Nutzlast, die eine Maschine nicht ausführen darf. Sie haben entgegengesetzte Erfolgskriterien. Eine Schwärzung ist korrekt, wenn sensibler Inhalt weg ist und der Rest wortwörtlich erhalten bleibt. Eine Entschärfung ist korrekt, wenn die Bedrohung weg ist, und sie ist durchaus bereit, gutartige Struktur zu verändern, um dorthin zu gelangen. Verwenden Sie das Werkzeug, das Ihrer Absicht entspricht; greifen Sie nicht zu dem einen und erwarten Sie die Zusicherungen des anderen.
Ein zweites Missverständnis ist, dass ein sauberer Neuaufbau beweist, dass das Original sauber war. Es beweist nichts über das Original. Es beweist nur, dass die Ausgabe keine erkannte Bedrohung enthält. Die Eingabe mag eine Waffe gewesen sein; CDRs Aufgabe ist es, sicherzustellen, dass das, was Sie weiter unten in die Kette weiterleiten, es nicht ist.
Grenzen und Abgrenzungen
Abschnitt betitelt „Grenzen und Abgrenzungen“Dies ist der Teil, den die Broschüren auslassen, also sagen wir es klar.
- Die Ausgabe ist eine Sicherheitsprojektion, keine beweistaugliche Kopie. Der
CdrEngine-Quellcode trägt dies als architektonische rote Linie. Das bereinigte PDF darf nicht zur juristischen Beweissicherung, zum Hash-Vergleich gegen das Original oder als Archivkopie verwendet werden. Die Transformation ist von Natur aus zerstörend und nicht umkehrbar. - Erkennung hat einen Geltungsbereich. CDR entfernt die Bedrohungen, die es zu benennen weiß. Es ist eine starke, prüfbare Schicht in einem Defense-in-Depth-Stapel – keine Garantie, dass eine Datei frei von jeder möglichen künftigen Technik ist. Halten Sie es hinter derselben Upload-Validierung, denselben Content-Type-Prüfungen und derselben Behandlung mit geringsten Rechten, die der Datei-Upload-Leitfaden von OWASP beschreibt.
- Manche Richtlinien sind absichtlich verlustbehaftet. Die optionalen
Strip*-Fälle entfernen eingebettete Dateien, Signaturen, Formularfelder, Ebenen und 3D-Medien. Diese sind mächtig, und sie werden legitimen Inhalt löschen – etwa eine ZUGFeRD/Factur-X-Rechnungsnutzlast. Sie sind genau aus diesem Grund standardmäßig ausgeschaltet. Schalten Sie sie wissentlich ein. - Signaturen überleben einen Neuaufbau nicht. Die Datei neu aufzubauen ändert ihre Bytes, sodass jede ursprüngliche digitale Signatur nicht mehr zu ihrem Byte-Bereich passt. Ein entschärftes Dokument ist in Bezug auf die Quelle unsigniert. Wenn Sie ein signiertes Artefakt brauchen, signieren Sie die saubere Ausgabe als einen neuen Akt.
| Edition | Availability |
|---|---|
| Core | Nicht verfügbar. Der NextPDF-Core führt kein CDR durch. Er parst, rendert und schreibt PDFs; er erkennt keine Bedrohungen und baut keine nicht vertrauenswürdige Eingabe neu auf. |
| Pro | In der Pro-Edition nicht verfügbar. |
| Enterprise | Verfügbar über |
Verwandte Dokumente
Abschnitt betitelt „Verwandte Dokumente“- Wie PDF-Verschlüsselung wirklich funktioniert – die andere Hälfte des Umgangs mit sensiblen PDFs: Inhalt schützen gegenüber Fähigkeit entfernen.
- Fehler als Funktion – die Fail-closed-Philosophie,
die CDRs Zulassungskontroll-Ablehnungen und der
/Root-Schutz verkörpern. - Eine API, die sich weigert zu raten – warum ein Ergebnistyp, der bereinigt von abgelehnt unterscheidet, einen stillen Best-Effort schlägt.
Glossar
Abschnitt betitelt „Glossar“- CDR (Content Disarm & Reconstruction) – eine Bereinigungsstrategie, die eine nicht vertrauenswürdige Datei parst, aktive oder gefährliche Komponenten entfernt und aus dem sicheren Rest eine saubere Datei neu aufbaut, statt nach bekanntermaßen schlechten Signaturen zu suchen.
- Sicherheitsprojektion – eine bereinigte Ausgabe, die genug von der Quelle bewahrt, um nützlich zu sein, und zugleich die Entfernung von Bedrohungen garantiert. Sie ist bewusst nicht byte-getreu und nicht für Beweise, Hashing oder Archivierung geeignet.
- Zulassungskontrolle – das vorgeschaltete Tor vor der Bereinigung, das Dokumente ablehnt, die Ressourcengrenzen überschreiten (Objektanzahl, Seitenanzahl, Größe des dekodierten Streams, Inflationsverhältnis), bevor irgendeine Entschärfungsarbeit beginnt.
- Aktion – eine PDF-Konstruktion, die bei einem Auslöser wie Dokument-Öffnen oder einer Feldänderung etwas geschehen lässt; der Aktionstyp-Katalog (Spec: ISO 32000-2, §12.6.4ISO 32000-2 §12.6.4) umfasst JavaScript- und Launch-Aktionen, die kanonische CDR-Bedrohungsoberfläche.
- Hängende Referenz – ein Zeiger auf ein Objekt, das nach dem Filtern nicht mehr existiert. Die Referenz-Schrubb-Phase entfernt diese, sodass die neu aufgebaute Datei strukturell konsistent bleibt.