Pular para o conteúdo

NextPDF Symfony: segurança e operações

Os helpers de resposta aplicam um conjunto fixo de cabeçalhos de segurança. O DTO (data transfer object) da mensagem assíncrona valida o caminho de saída duas vezes. A assinatura é opcional e, no tier Pro, fica restrita ao perfil baseline documentado aqui.

NextPDF\Symfony\Http\PdfResponse aplica o mesmo conjunto de cabeçalhos a todas as respostas que constrói: inline, download e ambas as variantes de streaming. A constante no código-fonte confirma exatamente estes cabeçalhos:

CabeçalhoValor
Cache-Controlprivate, max-age=0, must-revalidate
Pragmapublic
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Content-Security-Policydefault-src 'none'
X-Robots-Tagnoindex, nofollow
Referrer-Policyno-referrer

Esses cabeçalhos reduzem o sniffing de content type, o enquadramento (framing), a indexação e o vazamento de referrer nos documentos gerados. As variantes com buffer também definem Content-Type: application/pdf e Content-Length. As variantes de streaming definem o content type e omitem Content-Length por design.

O bundle mantém esse conjunto de cabeçalhos fixo. Para adicionar ou alterar cabeçalhos, como um Cache-Control mais restritivo para downloads autenticados, ajuste o Response retornado no controller antes de devolvê-lo.

Content-Disposition e tratamento do nome de arquivo

Seção intitulada “Content-Disposition e tratamento do nome de arquivo”

PdfResponse monta o cabeçalho Content-Disposition de forma defensiva. PdfResponseTest verifica esse comportamento:

  • O nome de arquivo é sanitizado; separadores de caminho e sequências de traversal são removidos, de modo que um nome de arquivo como ../../../etc/passwd.pdf não consiga escapar do destino esperado.
  • Uma extensão .pdf é anexada quando ausente; uma extensão existente não é duplicada, nem mesmo um .PDF em maiúsculas.
  • Aspas duplas e barras invertidas são escapadas para a forma quoted-string.
  • Nomes de arquivo não ASCII recebem um fallback ASCII e uma variante filename*=UTF-8'' conforme a RFC-5987 (Request for Comments 5987).
  • Um nome de arquivo vazio usa document.pdf como fallback.

Passe um nome de arquivo influenciado pelo usuário somente após a verificação de autorização no nível da aplicação. O bundle sanitiza o valor para proteger o cabeçalho, não para fazer controle de acesso.

NextPDF\Symfony\Message\GeneratePdfMessage valida o caminho de saída no construtor. NextPDF\Symfony\Message\GeneratePdfHandler o revalida em tempo de execução antes de gravar. O construtor rejeita:

  • um caminho vazio ou que contenha um byte nulo;
  • um esquema de stream-wrapper como php://...;
  • um segmento de traversal .. que use separadores / ou \;
  • um caminho que não termine em .pdf (sem diferenciar maiúsculas de minúsculas);
  • um builderClass que não seja um nome de classe sintaticamente válido.

A segunda validação no handler é importante porque uma mensagem pode permanecer em uma fila entre o dispatch e o consumo. O handler não confia no caminho enfileirado e aplica novamente o path guard antes de salvar. Execute os workers sob uma conta de sistema com privilégio mínimo no sistema de arquivos, limitada ao diretório de saída pretendido.

GeneratePdfHandler resolve builders a partir de um service locator PHP Standard Recommendation 11 (PSR-11) indexado pelo nome de classe e rejeita tudo que não seja um PdfBuilderInterface. Como o locator expõe apenas os builders registrados, um builderClass controlado por um atacante em um payload de transporte adulterado não consegue instanciar uma classe arbitrária. Pela PSR-11, quando um container reporta um id como ausente, a resolução falha em vez de retornar silenciosamente algo inesperado (PSR-11 §1.1.2). Registre no locator apenas classes de builder confiáveis.

A assinatura digital não faz parte do bundle core. Ela é ativada somente quando nextpdf/premium (que instala o tier Pro) está presente e o compiler pass detecta as classes de assinatura do Pro. Com o bundle e o tier Pro instalados, a configuração de assinatura documentada e suportada é o perfil baseline B-B.

O nó de configuração signature.level aceita valores de string adicionais para compatibilidade de schema em toda a família de configurações do NextPDF. A capacidade de assinatura entregue e suportada por este bundle é B-B. A documentação do NextPDF Premium cobre perfis de assinatura além do B-B, seus requisitos e suas considerações operacionais. Eles não são descritos aqui intencionalmente.

Notas operacionais para o caminho de assinatura B-B:

  • O signer é registrado somente quando signature.enabled é true e signature.certificate está definido; caso contrário, a seção permanece inerte.
  • Forneça o certificado, a chave privada e a senha por meio de Symfony secrets ou variáveis de ambiente. Nunca faça commit deles no repositório.
  • Restrinja as permissões de leitura do material da chave à conta da aplicação.

Os registries de fontes e imagens aceitam um Psr\Log\LoggerInterface opcional, vinculado com nullOnInvalid(). Quando presente, ele é um colaborador substituível sob o contrato de logger PHP Standard Recommendation 3 (PSR-3) (PSR-3). Remova dados que identifiquem o usuário de qualquer contexto de log que você adicionar ao redor da geração de documentos; o bundle não registra o conteúdo do documento.

  • Mantenha os cabeçalhos de resposta fixos; aplique um cache mais restritivo para downloads autenticados no controller.
  • Autorize a requisição antes de gerar ou retornar um documento; o bundle não executa controle de acesso.
  • Armazene o material da chave de assinatura em Symfony secrets / variáveis de ambiente com permissões de arquivo de privilégio mínimo.
  • Execute os workers do Messenger sob uma conta de privilégio mínimo com acesso de gravação limitado ao diretório de saída.
  • Mantenha ext-mbstring e ext-zlib habilitadas (caso contrário, o bundle falha rápido).
  • Fixe uma única major de nextpdf/core na aplicação para tornar a versão do engine determinística entre os deploys.

Cada linha é uma afirmação normativa feita nesta página, vinculada a um reference_id completo de 64 hex do corpus restrito da standards development organization (SDO). A proveniência (manifesto do corpus, transporte de recuperação) está em _sidecars/rag-citations.yaml.

SpecCláusulareference_idAfirmação
PSR-11psr_11_container#1.1.2.p5has() false implica que get() lança NotFoundException
PSR-3psr_3_logger#x3.p17Colaborador de logger opcional

A assinatura digital está disponível somente quando nextpdf/premium (Pro) está instalado; o perfil entregue por este bundle é o baseline B-B. Essa capacidade Pro opcional não exige nenhuma alteração de código no bundle Core documentado aqui. Consulte </get-license/?intent=symfony-pro>.

  • /integrations/symfony/production-usage/ — segurança de workers e streaming.
  • /integrations/symfony/configuration/ — tabelas de signature, tsa e service.
  • /integrations/symfony/troubleshooting/ — diagnóstico de problemas de assinatura e do Messenger.
  • /integrations/symfony/integration/ — referência de wiring de ponta a ponta.