Salta ai contenuti
getnextpdf.com

Enterprise edizione

Content Disarm and Reconstruction — Riferimento approfondito

Questa pagina è il riferimento approfondito per il modulo NextPDF\Enterprise\Security\Cdr. Il modulo disarma un PDF non attendibile e ricostruisce un file pulito a partire dai suoi oggetti sicuri. La pipeline è: analisi, controllo di ammissione, rilevamento delle minacce, filtraggio, ripulitura dei riferimenti, ricostruzione. L’output è una proiezione di sicurezza dell’input, mai una copia probatoria. Per una guida al flusso di lavoro, leggere prima la pagina della funzionalità CDR.

Questa funzionalità è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di livello Enterprise. Un deployment privo di quel diritto non carica le classi della funzionalità. Confronta le edizioni e ottieni una licenza.

SimboloParametriComportamento predefinitoRestituisceSolleva o fallisce conNote
CdrEngine::__constructnessunoCostruisce il detector e il rebuilder interniCdrEngineNulla dichiaratoNessun collaboratore iniettabile
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullEsegue l’intera pipeline sotto CdrPolicy::standard()CdrResultNon solleva eccezioni su input ostile; i fallimenti di analisi e ammissione restituiscono un risultato rifiutatoIl risultato segnala il rifiuto in modo distinto dalla sanificazione
CdrPolicy::__constructsette parametri nominati opzionali, vedere il bloccoSet di rimozione vuoto; allowUriActions false; flattenIncrementalUpdates true; limiti 100000 oggetti, 256 MiB decodificati, 10000 pagine, 1000.0 di inflazioneCdrPolicyNulla dichiaratofinal readonly; un elenco removeThreatTypes vuoto non rileva nulla
CdrPolicy::standardnessunoSet di minacce legacy; azioni URI rimosse; limiti predefinitiselfNulla dichiaratoEsclude i sette casi Strip* con perdita
CdrPolicy::paranoidnessunoSet di minacce legacy con limiti più stretti: 50000 oggetti, 128 MiB, 5000 pagine, 100.0 di inflazioneselfNulla dichiaratoEsclude i sette casi Strip* con perdita
CdrPolicy::permissivenessunoRimuove solo JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; preserva le azioni URIselfNulla dichiaratoDestinato a sorgenti attendibili
CdrPolicy::allThreatTypesnessunoRestituisce ogni caso ThreatType, inclusi i casi Strip* con perditalist<ThreatType>Nulla dichiaratoIl consenso esplicito allo strip massimale
CdrPolicy::legacyThreatTypesnessunoRestituisce ogni caso tranne i sette casi Strip*list<ThreatType>Nulla dichiaratoSet di rimozione predefinito per standard() e paranoid()
CdrPolicy::shouldRemoveThreatType $typeTest di appartenenza rispetto a removeThreatTypesboolNulla dichiaratoRestituisce false per UriAction quando allowUriActions è true
ThreatDetector::detectPdfReader $reader, CdrPolicy $policyAnalizza ogni oggetto e il catalogo del trailer per i tipi di minaccia del criteriolist<DetectedThreat>Non solleva eccezioni; un oggetto non analizzabile diventa una minaccia UnparseableObjectLa scansione del catalogo copre l’albero /Names/JavaScript
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policySerializza gli oggetti sicuri in un file %PDF-2.0 a revisione singolastringNulla dichiarato; gli oggetti che falliscono la rilettura o la validazione di /Length vengono saltati$policy è riservato per future modifiche di serializzazione
DetectedThreat::__constructThreatType $type, int $objectNumber, string $description, string $location = ''Value object immutabile del rilevamentoDetectedThreatNulla dichiaratoTutte e quattro le proprietà sono public readonly
ThreatTypeenum con backing stringVenti casi: tredici legacy più sette casi Strip* opzionalin/dn/dVedere l’inventario dei casi più sotto
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

Tredici casi legacy formano il set di rimozione predefinito. I casi Strip* sono con perdita per progettazione e non entrano mai in un criterio predefinito.

CasoValore di backingSuperficie di rilevamento
ThreatType::JavaScriptjavascriptChiave /JS su qualsiasi oggetto, oppure un’azione /S /JavaScript
ThreatType::AdditionalActionsadditional-actionsDizionario /AA su qualsiasi oggetto
ThreatType::OpenActionopen-actionChiave /OpenAction su qualsiasi oggetto
ThreatType::LaunchActionlaunch-actionAzione /S /Launch
ThreatType::RemoteGoToremote-gotoAzione /S /GoToR o /S /GoToE
ThreatType::SubmitFormsubmit-formAzione /S /SubmitForm
ThreatType::ImportDataimport-dataAzione /S /ImportData
ThreatType::EmbeddedFilesembedded-filesAlbero di nomi /EmbeddedFiles o dizionario /EF
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptAlbero di nomi /Names/JavaScript del catalogo
ThreatType::UriActionuri-actionAzione /S /URI; soppressa quando allowUriActions è true
ThreatType::XfaxfaChiave /XFA
ThreatType::UnparseableObjectunparseable-objectQualsiasi oggetto o catalogo la cui analisi fallisce
ThreatType::StripJavaScriptstrip-javascriptSuperset opzionale: chiave /JS, /S /JavaScript o /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesOpzionale: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles o /EF
ThreatType::StripFormFieldsstrip-form-fieldsOpzionale: /Subtype /Widget, chiave /FT o chiave /AcroForm
ThreatType::StripAnnotationsRichstrip-annotations-richSottotipi opzionali: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultOpzionale: /Type /OCG con una chiave /Usage o /Visibility
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildOpzionale: /Type /Sig, /FT /Sig, /DSS, /VRI o /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaSottotipi opzionali: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize esegue sei fasi ordinate e non solleva mai eccezioni per input ostile.

  1. Analisi. Un fallimento di analisi restituisce un risultato con admitted false e un motivo di rifiuto per errore di analisi. In quel caso l’output sanificato è vuoto.
  2. Controllo di ammissione. Il conteggio degli oggetti, i byte aggregati dei flussi decodificati, il rapporto di inflazione per flusso e il conteggio delle pagine sono verificati rispetto ai limiti del criterio. Un documento oltre i limiti viene rifiutato, non sanificato. Rifiuto e sanificazione sono segnalati in modo distinto.
  3. Rilevamento. ThreatDetector::detect analizza ogni oggetto e il catalogo del trailer per i tipi di minaccia del criterio. Gli oggetti non analizzabili vengono registrati come rilevamenti ThreatType::UnparseableObject anziché saltati.
  4. Filtraggio. Gli oggetti che presentano rilevamenti vengono messi in coda per la rimozione. Il catalogo del documento non viene mai rimosso come oggetto intero. I rilevamenti a livello di catalogo (OpenAction, AdditionalActions, NamedJavaScript) vengono invece rimediati tramite rimozione delle chiavi.
  5. Ripulitura dei riferimenti. Ogni riferimento indiretto a un oggetto rimosso viene sostituito con null durante la serializzazione.
  6. Ricostruzione. CdrRebuilder::rebuild emette un file %PDF-2.0 a revisione singola con oggetti rinumerati, una tabella di riferimenti incrociati classica e un trailer nuovo. I byte dei flussi sicuri vengono copiati byte per byte in modo identico. Il catalogo ricostruito elimina /OpenAction, /AA e /Names; /AA viene eliminato da ogni oggetto.

Il CdrResult restituito espone i byte ricostruiti, l’elenco delle minacce rimosse, entrambe le dimensioni in byte, il flag di ammissione e il motivo del rifiuto. Se la sorgente aveva un /Root risolvibile e l’output ricostruito lo ha perso, il motore rifiuta l’output anziché restituire un file strutturalmente rotto. Si tratta di una garanzia fail-closed: admitted true implica che l’output porti ancora un riferimento al catalogo del documento.

Gli aggiornamenti incrementali non sopravvivono mai: la ricostruzione serializza esattamente una revisione sotto ogni criterio, quindi le revisioni tardive di tipo shadow vengono appiattite per costruzione. Le firme digitali originali non possono restare valide attraverso una ricostruzione, perché gli intervalli di byte non corrispondono più all’output.

Linea rossa architetturale. CDR è un livello di proiezione di sicurezza, non un livello di conservazione. L’output non deve essere usato per la conservazione di prove legali, il confronto di hash con l’originale o copie di archiviazione.

  • Un criterio null si risolve in CdrPolicy::standard(). Un criterio costruito con il removeThreatTypes vuoto predefinito non rileva e non rimuove nulla.
  • allowUriActions impostato a true sopprime la rimozione di UriAction anche quando il caso è presente in removeThreatTypes.
  • flattenIncrementalUpdates è dichiarativo in questa release: la ricostruzione emette una revisione singola sotto ogni criterio, incluso permissive(), che imposta il flag a false.
  • Il controllo del rapporto di inflazione tratta come uno una lunghezza di flusso grezzo pari a zero, così che un flusso che si espande dal nulla resti comunque limitato. Quando nessuna forma decodificata viene mantenuta, la lunghezza del flusso grezzo conta ai fini del budget aggregato.
  • Il controllo di ammissione sul conteggio delle pagine è best-effort: un fallimento nella lettura del catalogo o dell’albero delle pagine non rifiuta di per sé il documento. I budget del conteggio degli oggetti e della decompressione sono sempre applicati.
  • Un oggetto la cui lunghezza di flusso grezzo non concorda con la sua voce intera /Length viene saltato in fase di ricostruzione (difesa dai poliglotti). Un riferimento a un oggetto così saltato mantiene il suo numero d’oggetto di origine e potrebbe non risolversi nell’output. sanitize() rifiuta i risultati rilevabilmente rotti (un /Root mancante), ma un chiamante che pilota direttamente il CdrRebuilder::rebuild() di basso livello deve rivalidare da sé la struttura dell’output e l’integrità dei riferimenti.
  • Quando il trailer di origine porta /ID, il trailer ricostruito porta un /ID casuale generato ex novo, non l’originale. Le altre voci del trailer, incluso /Info, non vengono riportate; il trailer ricostruito contiene /Size, /Root quando risolvibile e l’/ID rigenerato.
  • I byte di nomi e chiavi decodificati vengono riemessi con escape esadecimali per delimitatori, spazi bianchi e byte non stampabili, così che nomi ostili non possano iniettare sintassi di dizionario nell’output.
  • I valori stringa sotto chiavi di dizionario esterne al set noto valorizzato a nomi vengono emessi in modo conservativo come stringhe letterali.
  • CdrPolicy::legacyThreatTypes() tratta qualsiasi caso enum futuro come rimosso per impostazione predefinita a meno che non sia registrato come un caso Strip*, così che nuovi casi con perdita non possano entrare silenziosamente nei criteri predefiniti.
  • CDR non è un modulo crittografico. Il suo unico uso di casualità è l’/ID del trailer rigenerato. La validazione delle firme è fuori ambito qui; vedere il Riferimento approfondito sulle firme.
AffermazioneStandardClausola
L’invocazione di un’azione ECMAScript fa sì che un processore PDF esegua lo script incorporato.ISO 32000-2§12.6.4.17
Gli script a livello di documento nell’albero di nomi JavaScript vengono eseguiti tutti all’apertura del documento.ISO 32000-2§12.6.4.17
Il dizionario dei nomi del catalogo può contenere un albero di nomi JavaScript di azioni di script a livello di documento.ISO 32000-2§7.7.4 (Table 32)
Un’azione launch avvia un’applicazione, oppure apre o stampa un documento.ISO 32000-2§12.6.4.6
I dizionari di azioni aggiuntive /AA estendono gli eventi trigger su annotazioni, pagine, campi e catalogo.ISO 32000-2§12.6.3
L’acquisizione di file non attendibili deve limitare la presenza, il volume e il contenuto dei file in ingresso.OWASP ASVS 5.0§5.2
I sistemi dovrebbero impedire l’esecuzione inappropriata dei file caricati e rilevare contenuti pericolosi.OWASP ASVS 5.0§5.3

Tutte le clausole sono parafrasate; NextPDF non riproduce testo normativo. NextPDF non avanza alcuna rivendicazione di certificazione. CDR rimuove le superfici di contenuto attivo enumerate da ThreatType sotto il criterio configurato; è una capacità, non un sanificatore certificato. CDR non è uno scanner antivirus e non rileva firme di malware; complementa, e non soddisfa, controlli come la scansione antivirus OWASP ASVS 5.4.3. Se un file disarmato sia accettabile per una data pipeline di acquisizione resta una decisione di rischio dell’operatore.

  • Il sorgente del modulo porta @since 1.9.0; questo riferimento documenta la superficie così come rilasciata in nextpdf/enterprise 3.1.0.
  • Tutto viene eseguito in-process sul tuo host. Nessun accesso di rete avviene durante la sanificazione.
  • CdrPolicy e DetectedThreat sono final readonly; costruire una nuova istanza di criterio per modificare i limiti.
  • CdrEngine costruisce internamente il proprio detector e rebuilder. ThreatDetector e CdrRebuilder restano utilizzabili direttamente per pipeline a stadi che forniscono il proprio PdfReader.
  • Il parametro $policy di CdrRebuilder::rebuild è attualmente riservato; il sorgente lo documenta come mantenuto per compatibilità dei siti di chiamata e future modifiche di serializzazione per criterio.
  • L’output è strutturalmente riproducibile, non riproducibile bit per bit: l’/ID rigenerato differisce ad ogni esecuzione quando la sorgente ne portava uno.
  • Il tipo di risultato CdrResult (valore di ritorno di sanitize()) è trattato comportamentalmente più sopra; i suoi campi sono public readonly, con hadThreats() e threatCount() come utilità.

Questa pagina documenta solo il comportamento osservabile esternamente e la superficie dell’API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi dei file di runbook e i prefissi dei ticket sono fuori ambito.