Enterprise edition
Content Disarm and Reconstruction (CDR)
At a glance
Section titled “At a glance”NextPDF Enterprise neutralises an untrusted PDF by Content Disarm and Reconstruction (CDR): it parses the file, checks it against admission limits, detects dangerous features, removes them, and rebuilds a new file from the objects that remain. The dangerous features are active content — embedded scripts, launch actions, embedded files, rich media, and similar — that a viewer might execute or act on. This page is behaviour-level: it states what the engine admits, what it strips, what it rebuilds, and why the output is not an evidentiary copy.
CDR is a destructive, one-way transformation. The rebuilt output is a security projection of the input, not a preserved or hash-equivalent copy. That boundary is stated under Security and compliance.
Prerequisites are stated in the front matter and repeated under Prerequisites.
Availability & licensing
Section titled “Availability & licensing”This capability ships in NextPDF Enterprise (nextpdf/enterprise) and activates with an Enterprise-tier license envelope. A deployment without that entitlement does not load the capability’s classes. NextPDF Core and NextPDF Pro do not provide CDR. The engine runs in process; the untrusted document is parsed and rebuilt on your host. Compare editions and get a license.
What this capability does
Section titled “What this capability does”PDF supports active content that a viewer can execute or act on. An ECMAScript action causes a PDF processor to execute a script that can change field values and appearances, per ISO 32000-2 §12.6.4. A launch action launches an application or opens or prints a document, per ISO 32000-2 §12.6.4. Document-level scripts in the name dictionary run automatically when the document is opened, per ISO 32000-2 §7.7.4. CDR removes these surfaces.
The engine runs an ordered pipeline:
- Parse the input PDF.
- Admission control — verify the document is within the acceptance boundary (object count, page count, decoded-stream size, and a stream-inflation ratio that defends against decompression-bomb inputs). A document outside the limits is rejected, not sanitised. The rejection is reported distinctly from a sanitisation result so your error handling can tell the two apart.
- Detect threats — scan for the configured threat types.
- Filter — partition objects into the safe set and the removed set.
- Reference scrub — clean pointers left dangling by removal.
- Rebuild — serialise the safe objects into a new PDF.
The detectable threat types include embedded scripts (and aggressive script stripping that catches scripts in malformed structures), additional-actions and open-action triggers, launch actions, remote go-to actions, form submit and import-data actions, embedded files, rich media and three-dimensional content, document-level script name trees, external Uniform Resource Identifier (URI) actions, XML Forms Architecture data, interactive form fields, non-default optional-content layers, and digital-signature objects (which a rebuild necessarily invalidates because the byte ranges no longer match). An object that cannot be parsed is itself treated as a potential bypass and removed.
Three policies set the defaults:
- Standard — removes the engine-detectable, configured active-content threat types; incremental updates are always flattened to defend against signature-shadowing, and that flattening is not configurable in this mode.
- Paranoid — the same removals with tighter resource limits.
- Permissive — for trusted sources: removes scripts and launch actions but preserves URI actions, and makes incremental-update flattening configurable.
Why it works this way
Section titled “Why it works this way”CDR rebuilds a new file from the objects it judged safe, rather than deleting dangerous keys in place. That allow-list posture is the load-bearing decision. An object the detector never recognised — including one it could not parse — does not survive into the output, so an unknown structure fails closed instead of slipping through a deny-list gap. Admission control runs first for the same reason: an over-limit or unparseable input is rejected outright, never partially rebuilt. The cost of that safety is preservation. The rebuild changes the byte layout, invalidates signatures, and drops payloads whose threat type is stripped — which is why the output is a security projection, never an evidentiary copy.
Design background: Sanitizing untrusted PDFs: content disarm and reconstruction.
Prerequisites
Section titled “Prerequisites”- Install NextPDF Core and the Enterprise package, and hold an active Enterprise license.
- Define the acceptance boundary for your inputs — the maximum object count, page count, decoded-stream size, and inflation ratio — or use a preset policy’s limits.
- Decide the policy: standard for general untrusted intake, paranoid for the strictest posture, or permissive only for trusted sources.
Configuration
Section titled “Configuration”The policy is immutable and carries:
- Threat types to remove — the set the detector scans for and the rebuilder strips.
- URI-action handling — whether external URI actions are preserved.
- Incremental-update flattening — always on in standard and paranoid; configurable in permissive.
- Admission limits — maximum object count, page count, decoded-stream size, and inflation ratio. These are the acceptance boundary, not sanitisation behaviour; exceeding them rejects the document.
Step-by-step
Section titled “Step-by-step”- Read the untrusted PDF bytes.
- Select a policy (standard, paranoid, or permissive) or build one with explicit limits.
- Run the engine’s sanitise operation with the bytes and the policy.
- Inspect the result: if it reports not admitted, surface the rejection reason; otherwise use the rebuilt bytes and the list of removed threats.
- Treat the rebuilt output as a sanitised projection, never as an evidentiary or archival copy of the input.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Enterprise\Security\Cdr\CdrEngine;use NextPDF\Enterprise\Security\Cdr\CdrPolicy;use NextPDF\Enterprise\Security\Cdr\CdrResult;use Psr\Log\LoggerInterface;
final readonly class UntrustedPdfIntake{ public function __construct( private CdrEngine $engine, private LoggerInterface $logger, ) {}
/** * Sanitize an untrusted PDF and distinguish rejection from a clean rebuild. * * An over-limit document is rejected by admission control, not sanitized; * the caller surfaces the rejection reason instead of trusting an empty * output. The rebuilt bytes are a security projection, never an * evidentiary copy of the input. * * @param string $pdfBytes The untrusted PDF bytes. * * @return CdrResult The sanitization result, including admission status. */ public function sanitize(string $pdfBytes): CdrResult { $result = $this->engine->sanitize($pdfBytes, CdrPolicy::standard());
if (! $result->admitted) { $this->logger->warning('PDF rejected by CDR admission control', [ 'reason' => $result->rejectionReason, ]);
return $result; }
$this->logger->info('PDF sanitized', [ 'removedThreats' => \count($result->removedThreats), 'originalSize' => $result->originalSize, 'sanitizedSize' => $result->sanitizedSize, ]);
return $result; }}Verification
Section titled “Verification”- Run a sample carrying a known active-content surface (for example a document-level script) and confirm it appears in the removed-threats list and is absent from the rebuilt output.
- Run an over-limit document and confirm the result reports not admitted with a rejection reason, and the rebuilt bytes are empty.
- Confirm a digitally signed input has its signature objects removed in the rebuild — a rebuild invalidates the original signature because the byte ranges change, so stale signature objects are stripped by design.
- Open the rebuilt output in a viewer and confirm no script executes on open.
Security and compliance
Section titled “Security and compliance”- Not for evidence. The rebuilt output is a destructive, non-reversible projection. Do not use it for legal evidence preservation, for hash comparison with the original, or as an archival copy. Keep the original under separate custody if you need an evidentiary copy.
- Admission before sanitisation. Resource limits are an acceptance boundary; an over-limit document is rejected, not sanitised. Report rejection distinctly so an over-limit input is never mistaken for a clean rebuild.
- Active content is removed. Scripts, launch actions, document-level script name trees, embedded files, rich media, and similar surfaces are stripped — the very actions a viewer would otherwise execute (ISO 32000-2 §12.6.4 ECMAScript action; launch action; document-level scripts §7.7.4).
- Signatures are invalidated by rebuild. Because the rebuild changes the byte layout, the original signature can no longer validate; signature objects are removed rather than left misleadingly in place.
- Lossy by design. Embedded-file payloads — including invoice attachments such as Factur-X — are removed when their threat type is stripped. CDR is a security projection, not a preservation layer.
This page concerns document security. Every normative source is paraphrased; no normative text is reproduced.
Failure handling
Section titled “Failure handling”- Parse failure. A document that cannot be parsed yields a not-admitted result with a parse-error reason rather than a partial rebuild.
- Over-limit input. The result reports not admitted with a limit-specific reason; the rebuilt bytes are empty.
- Unparseable object. An object that cannot be parsed is treated as a potential bypass and removed, not silently kept.
- Best-effort page count. The page-count admission check is best-effort; a malformed catalog does not crash the pipeline, but object-count and stream limits still apply.
Publication boundary
Section titled “Publication boundary”This page documents externally observable behavior and the supported public API surface only. Internal namespace paths, helper classes, mechanism tables, runbook filenames, and ticket prefixes are out of scope.
See also
Section titled “See also”- Security — NextPDF Enterprise — the combined Enterprise security surface.
- Validation — NextPDF Enterprise — conformance checking of a produced or rebuilt PDF.
- Forensics — NextPDF Enterprise — document examination and tracing.
- Security — NextPDF Core — the core encryption and signature surface.
- CDR · active content · shadow attack — glossary terms.