Enterprise edição
Content Disarm and Reconstruction — Referência Profunda
Visão geral
Seção intitulada “Visão geral”Esta página é a referência detalhada do módulo NextPDF\Enterprise\Security\Cdr. O módulo desarma um PDF não confiável e reconstrói um arquivo limpo a partir de seus objetos seguros. O pipeline é: análise, controle de admissão, detecção de ameaças, filtragem, limpeza de referências, reconstrução. A saída é uma projeção de segurança da entrada, nunca uma cópia probatória. Para orientação de fluxo de trabalho, leia primeiro a página de capacidade do CDR.
Disponibilidade e licenciamento
Seção intitulada “Disponibilidade e licenciamento”Esta capacidade é distribuída no NextPDF Enterprise (nextpdf/enterprise) e é ativada com um envelope de licença de nível Enterprise. Uma implantação sem esse direito não carrega as classes da capacidade. Compare edições e obtenha uma licença.
Superfície da API pública
Seção intitulada “Superfície da API pública”| Símbolo | Parâmetros | Comportamento padrão | Retorna | Lança ou falha com | Notas |
|---|---|---|---|---|---|
CdrEngine::__construct | nenhum | Constrói o detector e o reconstrutor internos | CdrEngine | Nada declarado | Sem colaboradores injetáveis |
CdrEngine::sanitize | string $pdfData, ?CdrPolicy $policy = null | Executa o pipeline completo sob CdrPolicy::standard() | CdrResult | Não lança em entrada hostil; falhas de análise e de admissão retornam um resultado rejeitado | O resultado relata a rejeição de forma distinta da sanitização |
CdrPolicy::__construct | sete parâmetros nomeados opcionais, veja o bloco | Conjunto de remoção vazio; allowUriActions false; flattenIncrementalUpdates true; limites de 100000 objetos, 256 MiB decodificados, 10000 páginas, inflação de 1000.0 | CdrPolicy | Nada declarado | final readonly; uma lista removeThreatTypes vazia não detecta nada |
CdrPolicy::standard | nenhum | Conjunto de ameaças legado; ações URI removidas; limites padrão | self | Nada declarado | Exclui os sete casos Strip* com perdas |
CdrPolicy::paranoid | nenhum | Conjunto de ameaças legado com limites mais rígidos: 50000 objetos, 128 MiB, 5000 páginas, inflação de 100.0 | self | Nada declarado | Exclui os sete casos Strip* com perdas |
CdrPolicy::permissive | nenhum | Remove apenas JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; preserva ações URI | self | Nada declarado | Destinado a fontes confiáveis |
CdrPolicy::allThreatTypes | nenhum | Retorna todos os casos de ThreatType, incluindo os casos Strip* com perdas | list<ThreatType> | Nada declarado | A adesão explícita à remoção máxima |
CdrPolicy::legacyThreatTypes | nenhum | Retorna todos os casos exceto os sete casos Strip* | list<ThreatType> | Nada declarado | Conjunto de remoção padrão para standard() e paranoid() |
CdrPolicy::shouldRemove | ThreatType $type | Teste de pertencimento em removeThreatTypes | bool | Nada declarado | Retorna false para UriAction quando allowUriActions é true |
ThreatDetector::detect | PdfReader $reader, CdrPolicy $policy | Varre cada objeto e o catálogo do trailer em busca dos tipos de ameaça da política | list<DetectedThreat> | Não lança; um objeto não analisável se torna uma ameaça UnparseableObject | A varredura do catálogo cobre a árvore /Names/JavaScript |
CdrRebuilder::rebuild | PdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policy | Serializa os objetos seguros em um arquivo %PDF-2.0 de revisão única | string | Nada declarado; objetos que falham na releitura ou na validação de /Length são ignorados | $policy está reservado para futuros ajustes de serialização |
DetectedThreat::__construct | ThreatType $type, int $objectNumber, string $description, string $location = '' | Objeto de valor imutável de descoberta | DetectedThreat | Nada declarado | Todas as quatro propriedades são public readonly |
ThreatType | enum baseado em string | Vinte casos: treze legados mais sete casos Strip* opcionais | n/a | n/a | Veja o inventário de casos abaixo |
Assinaturas dos pontos de entrada
Seção intitulada “Assinaturas dos pontos de entrada”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: stringInventário de casos da ThreatType
Seção intitulada “Inventário de casos da ThreatType”Treze casos legados formam o conjunto de remoção padrão. Os casos Strip* têm perdas por design e nunca entram em uma política padrão.
| Caso | Valor de apoio | Superfície de detecção |
|---|---|---|
ThreatType::JavaScript | javascript | chave /JS em qualquer objeto, ou uma ação /S /JavaScript |
ThreatType::AdditionalActions | additional-actions | dicionário /AA em qualquer objeto |
ThreatType::OpenAction | open-action | chave /OpenAction em qualquer objeto |
ThreatType::LaunchAction | launch-action | ação /S /Launch |
ThreatType::RemoteGoTo | remote-goto | ação /S /GoToR ou /S /GoToE |
ThreatType::SubmitForm | submit-form | ação /S /SubmitForm |
ThreatType::ImportData | import-data | ação /S /ImportData |
ThreatType::EmbeddedFiles | embedded-files | árvore de nomes /EmbeddedFiles ou dicionário /EF |
ThreatType::RichMedia | rich-media | /Subtype /RichMedia |
ThreatType::NamedJavaScript | named-javascript | árvore de nomes /Names/JavaScript do catálogo |
ThreatType::UriAction | uri-action | ação /S /URI; suprimida quando allowUriActions é true |
ThreatType::Xfa | xfa | chave /XFA |
ThreatType::UnparseableObject | unparseable-object | Qualquer objeto ou catálogo que falha na análise |
ThreatType::StripJavaScript | strip-javascript | Superconjunto opcional: chave /JS, /S /JavaScript ou /Subtype /JavaScript |
ThreatType::StripEmbeddedFiles | strip-embedded-files | Opcional: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles ou /EF |
ThreatType::StripFormFields | strip-form-fields | Opcional: /Subtype /Widget, chave /FT ou chave /AcroForm |
ThreatType::StripAnnotationsRich | strip-annotations-rich | Subtipos opcionais: Movie, Sound, FileAttachment, 3D, RichMedia, Screen |
ThreatType::StripOcgNonDefault | strip-ocg-non-default | Opcional: /Type /OCG com uma chave /Usage ou /Visibility |
ThreatType::StripDigitalSignaturesAtRebuild | strip-digital-signatures-at-rebuild | Opcional: /Type /Sig, /FT /Sig, /DSS, /VRI ou /ByteRange |
ThreatType::Strip3dAndRichMedia | strip-3d-and-rich-media | Subtipos opcionais: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie |
Contrato de comportamento
Seção intitulada “Contrato de comportamento”CdrEngine::sanitize executa seis fases ordenadas e nunca lança para entrada hostil.
- Análise. Uma falha de análise retorna um resultado com
admittedfalse e um motivo de rejeição de erro de análise. A saída sanitizada fica vazia nesse caso. - Controle de admissão. A contagem de objetos, o total agregado de bytes de fluxo decodificados, a razão de inflação por fluxo e a contagem de páginas são verificados em relação aos limites da política. Um documento acima do limite é rejeitado, não sanitizado. Rejeição e sanitização são relatadas de forma distinta.
- Detecção.
ThreatDetector::detectvarre cada objeto e o catálogo do trailer em busca dos tipos de ameaça da política. Objetos não analisáveis são registrados como descobertasThreatType::UnparseableObjectem vez de ignorados. - Filtragem. Objetos que carregam descobertas são enfileirados para remoção. O catálogo do documento nunca é removido como objeto inteiro. Descobertas em nível de catálogo (
OpenAction,AdditionalActions,NamedJavaScript) são remediadas por remoção de chaves. - Limpeza de referências. Cada referência indireta a um objeto removido é substituída por
nulldurante a serialização. - Reconstrução.
CdrRebuilder::rebuildemite um arquivo%PDF-2.0de revisão única com objetos renumerados, uma tabela de referência cruzada clássica e um trailer novo. Os bytes de fluxo seguros são copiados de forma byte-idêntica. O catálogo reconstruído descarta/OpenAction,/AAe/Names;/AAé descartado de cada objeto.
O CdrResult retornado expõe os bytes reconstruídos, a lista de ameaças removidas, ambos os tamanhos em bytes, o sinalizador de admissão e o motivo de rejeição. Se a origem tinha um /Root resolvível e a saída reconstruída o perdeu, o motor rejeita a saída em vez de retornar um arquivo estruturalmente quebrado. Esta é uma garantia fail-closed: admitted true implica que a saída ainda carrega uma referência ao catálogo do documento.
Atualizações incrementais nunca sobrevivem: a reconstrução serializa exatamente uma revisão sob qualquer política, portanto revisões tardias no estilo shadow são achatadas por construção. Assinaturas digitais originais não podem permanecer válidas após uma reconstrução, porque os intervalos de bytes não correspondem mais à saída.
Linha vermelha de arquitetura. CDR é uma camada de projeção de segurança, não uma camada de preservação. A saída não deve ser usada para preservação de evidência legal, comparação de hash com o original ou cópias de arquivamento.
Casos extremos e modos de falha
Seção intitulada “Casos extremos e modos de falha”- Uma política
nullresolve paraCdrPolicy::standard(). Uma política construída com oremoveThreatTypesvazio padrão não detecta nem remove nada. allowUriActionsdefinido comotruesuprime a remoção deUriActionmesmo quando o caso está presente emremoveThreatTypes.flattenIncrementalUpdatesé declarativo nesta versão: a reconstrução emite uma única revisão sob qualquer política, incluindopermissive(), que define o sinalizador comofalse.- A verificação da razão de inflação trata um comprimento de fluxo bruto de zero como um, portanto um fluxo que infla a partir do nada ainda é limitado. Quando nenhuma forma decodificada é retida, o comprimento do fluxo bruto conta para o orçamento agregado.
- A verificação de admissão por contagem de páginas é de melhor esforço: uma falha de leitura do catálogo ou da árvore de páginas não rejeita o documento por si só. Os orçamentos de contagem de objetos e de descompressão são sempre aplicados.
- Um objeto cujo comprimento de fluxo bruto discorda de sua entrada inteira
/Lengthé ignorado no momento da reconstrução (defesa contra poliglota). Uma referência a esse objeto ignorado retém seu número de objeto de origem e pode não resolver na saída.sanitize()recusa resultados detectavelmente quebrados (um/Rootausente), mas um chamador que aciona diretamente oCdrRebuilder::rebuild()de baixo nível deve revalidar a estrutura da saída e a integridade das referências por conta própria. - Quando o trailer de origem carrega
/ID, o trailer reconstruído carrega um/IDaleatório recém-gerado, não o original. Outras entradas do trailer, incluindo/Info, não são transferidas; o trailer reconstruído mantém/Size,/Rootquando resolvível e o/IDregenerado. - Bytes de nomes e chaves decodificados são reemitidos com escapes hexadecimais para delimitadores, espaços em branco e bytes não imprimíveis, para que nomes hostis não possam injetar sintaxe de dicionário na saída.
- Valores de string sob chaves de dicionário fora do conjunto conhecido de valores nomeados são emitidos de forma conservadora como strings literais.
CdrPolicy::legacyThreatTypes()trata qualquer caso de enum futuro como removido por padrão, a menos que seja registrado como um casoStrip*, portanto novos casos com perdas não podem entrar silenciosamente em políticas padrão.- CDR não é um módulo criptográfico. Seu único uso de aleatoriedade é o
/IDregenerado do trailer. A validação de assinatura está fora do escopo aqui; consulte a referência detalhada de assinatura.
Conformidade
Seção intitulada “Conformidade”| Afirmação | Padrão | Cláusula |
|---|---|---|
| Invocar uma ação ECMAScript faz um processador de PDF executar o script incorporado. | ISO 32000-2 | §12.6.4.17 |
Scripts em nível de documento na árvore de nomes JavaScript são todos executados quando o documento abre. | ISO 32000-2 | §12.6.4.17 |
O dicionário de nomes do catálogo pode conter uma árvore de nomes JavaScript de ações de script em nível de documento. | ISO 32000-2 | §7.7.4 (Table 32) |
| Uma ação de inicialização inicia um aplicativo, ou abre ou imprime um documento. | ISO 32000-2 | §12.6.4.6 |
Dicionários de ações adicionais /AA estendem os eventos de disparo em anotações, páginas, campos e no catálogo. | ISO 32000-2 | §12.6.3 |
| A entrada de arquivos não confiáveis deve limitar a presença, o volume e o conteúdo dos arquivos recebidos. | OWASP ASVS 5.0 | §5.2 |
| Os sistemas devem impedir a execução inadequada de arquivos enviados e detectar conteúdo perigoso. | OWASP ASVS 5.0 | §5.3 |
Todas as cláusulas são parafraseadas; o NextPDF não reproduz texto normativo. O NextPDF não faz nenhuma alegação de certificação. O CDR remove as superfícies de conteúdo ativo enumeradas por ThreatType sob a política configurada; é uma capacidade, não um sanitizador certificado. O CDR não é um scanner antivírus e não detecta assinaturas de malware; ele complementa, e não satisfaz, controles como a varredura antivírus OWASP ASVS 5.4.3. Se um arquivo desarmado é aceitável para um determinado pipeline de entrada permanece a decisão de risco do operador.
Notas de desenvolvimento
Seção intitulada “Notas de desenvolvimento”- O código-fonte do módulo carrega
@since 1.9.0; esta referência documenta a superfície conforme distribuída nonextpdf/enterprise3.1.0. - Tudo é executado em processo no seu host. Nenhum acesso à rede ocorre durante a sanitização.
CdrPolicyeDetectedThreatsãofinal readonly; construa uma nova instância de política para alterar os limites.CdrEngineconstrói seu detector e reconstrutor internamente.ThreatDetectoreCdrRebuilderpermanecem diretamente utilizáveis para pipelines em etapas que fornecem seu próprioPdfReader.- O parâmetro
$policydeCdrRebuilder::rebuildestá atualmente reservado; o código-fonte o documenta como mantido para compatibilidade de local de chamada e futuros ajustes de serialização por política. - A saída é reproduzível estruturalmente, não bit a bit: o
/IDregenerado difere em cada execução quando a origem carregava um. - O tipo de resultado
CdrResult(valor de retorno desanitize()) é coberto comportamentalmente acima; seus campos sãopublic readonly, comhadThreats()ethreatCount()como conveniências.
Veja também
Seção intitulada “Veja também”- Content Disarm and Reconstruction (CDR) — a página de capacidade com orientação de fluxo de trabalho e de política.
- Segurança — Referência Detalhada
- Validação — Referência Detalhada
- Forense — Referência Detalhada
Limite de publicação
Seção intitulada “Limite de publicação”Esta página documenta apenas o comportamento observável externamente e a superfície de API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivos de runbook e prefixos de tíquetes estão fora do escopo.