Ga naar inhoud
getnextpdf.com

Enterprise editie

Content Disarm and Reconstruction — Diepe referentie

Deze pagina is de diepgaande referentie voor de NextPDF\Enterprise\Security\Cdr-module. De module ontwapent een niet-vertrouwde PDF en reconstrueert een schoon bestand uit de veilige objecten ervan. De pijplijn is: parsen, toelatingscontrole, dreigingsdetectie, filteren, referentiescrubbing, rebuild. De uitvoer is een beveiligingsprojectie van de invoer, nooit een bewijskopie. Lees voor workflow-begeleiding eerst de CDR-capaciteitspagina.

Deze functionaliteit wordt geleverd in NextPDF Enterprise (nextpdf/enterprise) en wordt geactiveerd met een licentie-envelop van de Enterprise-tier. Een deployment zonder die rechten laadt de klassen van de functionaliteit niet. Vergelijk edities en verkrijg een licentie.

SymboolParametersStandaardgedragRetourneertGooit of faalt metOpmerkingen
CdrEngine::__constructgeenConstrueert de interne detector en rebuilderCdrEngineNiets gedeclareerdGeen injecteerbare collaborators
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullVoert de volledige pijplijn uit onder CdrPolicy::standard()CdrResultGooit niet bij vijandige invoer; parse- en toelatingsfouten retourneren een afgewezen resultaatHet resultaat rapporteert afwijzing los van sanering
CdrPolicy::__constructzeven optionele benoemde parameters, zie fenceLege verwijderset; allowUriActions false; flattenIncrementalUpdates true; limieten 100000 objecten, 256 MiB gedecodeerd, 10000 pagina’s, 1000.0 inflatieCdrPolicyNiets gedeclareerdfinal readonly; een lege removeThreatTypes-lijst detecteert niets
CdrPolicy::standardgeenLegacy-dreigingsset; URI-acties verwijderd; standaardlimietenselfNiets gedeclareerdSluit de zeven lossy Strip*-cases uit
CdrPolicy::paranoidgeenLegacy-dreigingsset met strengere limieten: 50000 objecten, 128 MiB, 5000 pagina’s, 100.0 inflatieselfNiets gedeclareerdSluit de zeven lossy Strip*-cases uit
CdrPolicy::permissivegeenVerwijdert alleen JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; behoudt URI-actiesselfNiets gedeclareerdBedoeld voor vertrouwde bronnen
CdrPolicy::allThreatTypesgeenRetourneert elke ThreatType-case, inclusief de lossy Strip*-caseslist<ThreatType>Niets gedeclareerdDe expliciete opt-in voor maximale strip
CdrPolicy::legacyThreatTypesgeenRetourneert elke case behalve de zeven Strip*-caseslist<ThreatType>Niets gedeclareerdStandaardverwijderset voor standard() en paranoid()
CdrPolicy::shouldRemoveThreatType $typeLidmaatschapstest tegen removeThreatTypesboolNiets gedeclareerdRetourneert false voor UriAction wanneer allowUriActions true is
ThreatDetector::detectPdfReader $reader, CdrPolicy $policyScant elk object en de trailer-catalogus op de dreigingstypen van het beleidlist<DetectedThreat>Gooit niet; een niet-parseerbaar object wordt een UnparseableObject-dreigingCatalogusscan omvat de /Names/JavaScript-boom
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policySerialiseert veilige objecten in een %PDF-2.0-bestand met één revisiestringNiets gedeclareerd; objecten die falen bij herlezen of /Length-validatie worden overgeslagen$policy is gereserveerd voor toekomstige serialisatie-aanpassingen
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''Immutable value-object voor bevindingenDetectedThreatNiets gedeclareerdAlle vier de properties zijn public readonly
ThreatTypestring-backed enumTwintig cases: dertien legacy plus zeven opt-in Strip*-casesn/an/aZie de case-inventaris hieronder
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

Dertien legacy-cases vormen de standaardverwijderset. De Strip*-cases zijn lossy door ontwerp en komen nooit in een standaardbeleid terecht.

CaseBacking-waardeDetectieoppervlak
ThreatType::JavaScriptjavascript/JS-key op elk object, of een /S /JavaScript-actie
ThreatType::AdditionalActionsadditional-actions/AA-dictionary op elk object
ThreatType::OpenActionopen-action/OpenAction-key op elk object
ThreatType::LaunchActionlaunch-action/S /Launch-actie
ThreatType::RemoteGoToremote-goto/S /GoToR- of /S /GoToE-actie
ThreatType::SubmitFormsubmit-form/S /SubmitForm-actie
ThreatType::ImportDataimport-data/S /ImportData-actie
ThreatType::EmbeddedFilesembedded-files/EmbeddedFiles-name-tree of /EF-dictionary
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptCatalogus-/Names/JavaScript-name-tree
ThreatType::UriActionuri-action/S /URI-actie; onderdrukt wanneer allowUriActions true is
ThreatType::Xfaxfa/XFA-key
ThreatType::UnparseableObjectunparseable-objectElk object of elke catalogus die niet parseert
ThreatType::StripJavaScriptstrip-javascriptOpt-in-superset: /JS-key, /S /JavaScript, of /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesOpt-in: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles, of /EF
ThreatType::StripFormFieldsstrip-form-fieldsOpt-in: /Subtype /Widget, /FT-key, of /AcroForm-key
ThreatType::StripAnnotationsRichstrip-annotations-richOpt-in-subtypes: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultOpt-in: /Type /OCG met een /Usage- of /Visibility-key
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildOpt-in: /Type /Sig, /FT /Sig, /DSS, /VRI, of /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaOpt-in-subtypes: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize voert zes geordende fasen uit en gooit nooit bij vijandige invoer.

  1. Parsen. Een parse-fout retourneert een resultaat met admitted false en een parse-error als afwijzingsreden. De gesaneerde uitvoer is in dat geval leeg.
  2. Toelatingscontrole. Het aantal objecten, de totale gedecodeerde streambytes, de inflatieverhouding per stream en het aantal pagina’s worden gecontroleerd tegen de beleidslimieten. Een document dat de limiet overschrijdt wordt afgewezen, niet gesaneerd. Afwijzing en sanering worden apart gerapporteerd.
  3. Detectie. ThreatDetector::detect scant elk object en de trailer-catalogus op de dreigingstypen van het beleid. Niet-parseerbare objecten worden geregistreerd als ThreatType::UnparseableObject-bevindingen in plaats van overgeslagen.
  4. Filteren. Objecten met bevindingen worden in de wachtrij voor verwijdering gezet. De documentcatalogus wordt nooit als heel object verwijderd. Bevindingen op catalogusniveau (OpenAction, AdditionalActions, NamedJavaScript) worden in plaats daarvan verholpen door key-stripping.
  5. Referentiescrubbing. Elke indirecte referentie naar een verwijderd object wordt tijdens serialisatie vervangen door null.
  6. Rebuild. CdrRebuilder::rebuild produceert een %PDF-2.0-bestand met één revisie, hernummerde objecten, een klassieke cross-reference-tabel en een verse trailer. Veilige streambytes worden byte-identiek gekopieerd. De herbouwde catalogus laat /OpenAction, /AA en /Names vallen; /AA wordt uit elk object verwijderd.

Het geretourneerde CdrResult stelt de herbouwde bytes, de lijst met verwijderde dreigingen, beide bytegroottes, de toelatingsvlag en de afwijzingsreden beschikbaar. Als de bron een oplosbare /Root had en de herbouwde uitvoer die kwijtraakte, wijst de engine de uitvoer af in plaats van een structureel kapot bestand te retourneren. Dit is een fail-closed-garantie: admitted true impliceert dat de uitvoer nog steeds een verwijzing naar een documentcatalogus draagt.

Incrementele updates overleven nooit: de rebuild serialiseert onder elk beleid precies één revisie, dus shadow-achtige late revisies worden door constructie afgevlakt. Originele digitale handtekeningen kunnen na een rebuild niet geldig blijven, omdat de byte ranges niet meer overeenkomen met de uitvoer.

Architecturale rode lijn. CDR is een beveiligingsprojectielaag, geen behoudslaag. De uitvoer mag niet worden gebruikt voor juridisch bewijsbehoud, hashvergelijking met het origineel of archiefkopieën.

  • Een null-beleid wordt omgezet naar CdrPolicy::standard(). Een beleid dat is geconstrueerd met de standaard lege removeThreatTypes detecteert en verwijdert niets.
  • allowUriActions op true onderdrukt UriAction-verwijdering, zelfs wanneer de case aanwezig is in removeThreatTypes.
  • flattenIncrementalUpdates is declaratief in deze release: de rebuild produceert onder elk beleid één revisie, inclusief permissive(), dat de vlag op false zet.
  • De inflatieverhoudingscontrole behandelt een ruwe streamlengte van nul als één, zodat een stream die vanuit niets inflatert nog steeds begrensd is. Wanneer geen gedecodeerde vorm wordt behouden, telt de ruwe streamlengte mee voor het totaalbudget.
  • De toelatingscontrole op paginatelling is best-effort: een leesfout in de catalogus of paginaboom wijst het document op zichzelf niet af. De budgetten voor objecttelling en decompressie worden altijd afgedwongen.
  • Een object waarvan de ruwe streamlengte niet overeenkomt met zijn integer /Length-entry wordt bij de rebuild overgeslagen (polyglot-verdediging). Een verwijzing naar zo’n overgeslagen object behoudt zijn bronobjectnummer en wordt mogelijk niet opgelost in de uitvoer. sanitize() weigert detecteerbaar kapotte resultaten (een ontbrekende /Root), maar een aanroeper die de low-level CdrRebuilder::rebuild() rechtstreeks aanstuurt, moet de uitvoerstructuur en referentie-integriteit zelf opnieuw valideren.
  • Wanneer de brontrailer /ID draagt, draagt de herbouwde trailer een vers gegenereerde willekeurige /ID, niet het origineel. Andere trailer-entries, inclusief /Info, worden niet overgenomen; de herbouwde trailer bevat /Size, /Root wanneer oplosbaar, en de opnieuw gegenereerde /ID.
  • Gedecodeerde naam- en key-bytes worden opnieuw geëmitteerd met hexadecimale escapes voor scheidingstekens, witruimte en niet-afdrukbare bytes, zodat vijandige namen geen dictionary-syntaxis in de uitvoer kunnen injecteren.
  • Stringwaarden onder dictionary-keys buiten de bekende name-valued-set worden conservatief als literal strings geëmitteerd.
  • CdrPolicy::legacyThreatTypes() behandelt elke toekomstige enum-case als standaard-verwijderd, tenzij deze is geregistreerd als een Strip*-case, zodat nieuwe lossy-cases niet stilzwijgend in standaardbeleid terecht kunnen komen.
  • CDR is geen cryptografische module. Het enige gebruik van willekeur is de opnieuw gegenereerde trailer-/ID. Handtekeningvalidatie valt hier buiten scope; zie de Signature diepgaande referentie.
ClaimStandaardClausule
Het aanroepen van een ECMAScript-actie laat een PDF-processor het ingebedde script uitvoeren.ISO 32000-2§12.6.4.17
Document-niveau-scripts in de JavaScript-name-tree worden allemaal uitgevoerd wanneer het document opent.ISO 32000-2§12.6.4.17
De catalogus-name-dictionary kan een JavaScript-name-tree van document-niveau-scriptacties bevatten.ISO 32000-2§7.7.4 (Table 32)
Een launch-actie start een applicatie, of opent of print een document.ISO 32000-2§12.6.4.6
/AA-additional-actions-dictionaries breiden de trigger-events uit op annotaties, pagina’s, velden en de catalogus.ISO 32000-2§12.6.3
Intake van niet-vertrouwde bestanden moet de aanwezigheid, het volume en de inhoud van binnenkomende bestanden begrenzen.OWASP ASVS 5.0§5.2
Systemen moeten ongepaste uitvoering van geüploade bestanden voorkomen en gevaarlijke inhoud detecteren.OWASP ASVS 5.0§5.3

Alle clausules zijn geparafraseerd; NextPDF reproduceert geen normatieve tekst. NextPDF doet geen certificeringsclaim. CDR verwijdert de actieve-inhoudsoppervlakken die door ThreatType worden opgesomd onder het geconfigureerde beleid; het is een functionaliteit, geen gecertificeerde sanitizer. CDR is geen antivirusscanner en detecteert geen malwaresignatures; het vult controles zoals OWASP ASVS 5.4.3 antivirusscanning aan, maar voldoet er niet aan. Of een ontwapend bestand acceptabel is voor een bepaalde intakepijplijn blijft de risicobeslissing van de operator.

  • De modulebroncode draagt @since 1.9.0; deze referentie documenteert het oppervlak zoals geleverd in nextpdf/enterprise 3.1.0.
  • Alles draait in-process op je host. Er vindt geen netwerktoegang plaats tijdens sanering.
  • CdrPolicy en DetectedThreat zijn final readonly; construeer een nieuwe policy-instantie om limieten te wijzigen.
  • CdrEngine construeert zijn detector en rebuilder intern. ThreatDetector en CdrRebuilder blijven direct bruikbaar voor gefaseerde pijplijnen die hun eigen PdfReader leveren.
  • De $policy-parameter van CdrRebuilder::rebuild is momenteel gereserveerd; de broncode documenteert deze als behouden voor call-site-compatibiliteit en toekomstige per-policy-serialisatie-aanpassingen.
  • De uitvoer is structureel reproduceerbaar, niet bitgewijs reproduceerbaar: de opnieuw gegenereerde /ID verschilt bij elke run wanneer de bron er een droeg.
  • Het resultaattype CdrResult (retourwaarde van sanitize()) is hierboven gedragsmatig behandeld; zijn velden zijn public readonly, met hadThreats() en threatCount() als gemaksmethoden.

Deze pagina documenteert alleen extern waarneembaar gedrag en het ondersteunde publieke API-oppervlak. Interne namespace-paden, helperklassen, mechanismetabellen, runbook-bestandsnamen en ticket-prefixen vallen buiten scope.