Seguridad y operaciones de NextPDF en Symfony
De un vistazo
Sección titulada «De un vistazo»Los helpers de respuesta aplican un conjunto fijo de cabeceras de seguridad. El DTO del mensaje asíncrono valida dos veces la ruta de salida. La firma es opcional y, con el nivel Pro, queda limitada al perfil de referencia documentado aquí.
Cabeceras de seguridad de la respuesta HTTP
Sección titulada «Cabeceras de seguridad de la respuesta HTTP»NextPDF\Symfony\Http\PdfResponse aplica el mismo conjunto de cabeceras a cada respuesta que construye (en línea, descarga y ambas variantes transmitidas en streaming). Estas son las cabeceras exactas, verificadas contra la constante de origen:
| Cabecera | Valor |
|---|---|
Cache-Control | private, max-age=0, must-revalidate |
Pragma | public |
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Content-Security-Policy | default-src 'none' |
X-Robots-Tag | noindex, nofollow |
Referrer-Policy | no-referrer |
Estas cabeceras reducen el sniffing de content-type, el framing, la indexación y la fuga del referrer en los documentos generados. Las variantes con búfer establecen además Content-Type: application/pdf y Content-Length. Las variantes transmitidas en streaming establecen el content type, pero omiten Content-Length de forma intencionada.
El bundle fija el conjunto de cabeceras. Para añadir o cambiar cabeceras (por ejemplo, un Cache-Control más estricto para descargas autenticadas), modifica el Response devuelto en tu controlador antes de devolverlo.
Manejo de Content-Disposition y nombres de archivo
Sección titulada «Manejo de Content-Disposition y nombres de archivo»PdfResponse construye la cabecera Content-Disposition de forma defensiva, según se verifica en PdfResponseTest:
- El nombre de archivo se sanea; los separadores de ruta y las secuencias de traversal se eliminan (un nombre de archivo como
../../../etc/passwd.pdfno puede escapar). - Se añade una extensión
.pdfcuando falta; una extensión existente no se duplica, incluida una.PDFen mayúsculas. - Las comillas dobles y las barras invertidas se escapan para la forma de cadena entre comillas.
- Los nombres de archivo no ASCII reciben un fallback ASCII y una variante
filename*=UTF-8''de RFC-5987. - Un nombre de archivo vacío recurre a
document.pdf.
Pasa un nombre de archivo influido por el usuario solo después de realizar tu propia comprobación de autorización a nivel de aplicación; el bundle sanea para proteger las cabeceras, no para aplicar control de acceso.
Validación asíncrona de la ruta de salida
Sección titulada «Validación asíncrona de la ruta de salida»NextPDF\Symfony\Message\GeneratePdfMessage valida la ruta de salida en su constructor, y NextPDF\Symfony\Message\GeneratePdfHandler la vuelve a validar en tiempo de ejecución antes de escribir. Reglas de rechazo verificadas en la construcción:
- una ruta vacía, o una ruta que contenga un byte nulo;
- un esquema de stream wrapper como
php://...; - un segmento de traversal
..que use separadores/o\; - una ruta que no termine en
.pdf(sin distinguir mayúsculas de minúsculas); - un
builderClassque no sea un nombre de clase sintácticamente válido.
La segunda validación en el handler es importante porque un mensaje puede persistir en una cola entre el envío y el consumo. El handler no confía en la ruta encolada y vuelve a aplicar la protección de ruta antes de guardar. Ejecuta los workers bajo una cuenta del sistema de archivos con privilegios mínimos, acotada al directorio de salida previsto.
Límite de resolución del builder
Sección titulada «Límite de resolución del builder»GeneratePdfHandler resuelve los builders desde un service locator PSR-11 indexado por nombre de clase y rechaza todo lo que no sea un PdfBuilderInterface. Como el locator solo expone los builders registrados, un builderClass controlado por un atacante en un payload de transporte manipulado no puede instanciar una clase arbitraria. Bajo PSR-11, cuando un contenedor informa de que un id está ausente, la resolución falla en lugar de devolver silenciosamente algo inesperado (PSR-11 §1.1.2). Registra en el locator solo clases de builder de confianza.
Postura de firma digital opcional
Sección titulada «Postura de firma digital opcional»La firma digital no forma parte del bundle core. Se activa únicamente cuando nextpdf/premium (que instala el nivel Pro) está presente y el compiler pass detecta las clases de firma de Pro. Cuando el bundle y el nivel Pro están instalados, la configuración de firma compatible y documentada es el perfil baseline B-B.
El nodo de configuración signature.level acepta valores de cadena adicionales por compatibilidad de esquema en toda la familia de configuración de NextPDF. La capacidad de firma entregada y compatible en este bundle es B-B. Los perfiles de firma más allá de B-B, sus requisitos y sus consideraciones operativas están documentados en la documentación de NextPDF Premium y, de forma intencionada, no se describen aquí.
Notas operativas para la ruta de firma B-B:
- El firmante se registra solo cuando
signature.enabledes true ysignature.certificateestá definido; de lo contrario, la sección no tiene efecto. - Proporciona el certificado, la clave privada y la contraseña a través de los secrets de Symfony o de variables de entorno, nunca versionados en el repositorio.
- Restringe los permisos de lectura del material de claves a la cuenta de la aplicación.
Logging opcional
Sección titulada «Logging opcional»Los registros de fuentes e imágenes aceptan un Psr\Log\LoggerInterface opcional, enlazado con nullOnInvalid(). Si está presente, es un colaborador intercambiable según el contrato de logger PSR-3 (PSR-3). Elimina del contexto de log que añadas en torno a la generación de documentos cualquier dato que identifique al usuario; el bundle no registra el contenido de los documentos.
Lista de verificación de endurecimiento operativo
Sección titulada «Lista de verificación de endurecimiento operativo»- Mantén las cabeceras de respuesta fijas; añade en el controlador una política de caché más estricta para las descargas autenticadas.
- Autoriza la solicitud antes de generar o devolver un documento; el bundle no realiza control de acceso.
- Almacena el material de claves de firma en los secrets de Symfony o en variables de entorno, con permisos de archivo de mínimo privilegio.
- Ejecuta los workers de Messenger bajo una cuenta con privilegios mínimos, con acceso de escritura limitado al directorio de salida.
- Mantén habilitadas
ext-mbstringyext-zlib(de lo contrario el bundle falla rápido). - Fija un único major de
nextpdf/coreen la aplicación para que la versión del motor sea determinista en todos los despliegues.
Conformidad
Sección titulada «Conformidad»Cada fila representa una afirmación normativa realizada en esta página, anclada a un reference_id completo de 64 dígitos hexadecimales del corpus SDO controlado. La provenance (procedencia), incluidos el manifiesto del corpus y el transporte de recuperación, está en _sidecars/rag-citations.yaml.
| Especificación | Cláusula | reference_id | Afirmación |
|---|---|---|---|
| PSR-11 | psr_11_container#1.1.2.p5 | has() false implica que get() lanza NotFoundException | |
| PSR-3 | psr_3_logger#x3.p17 | Colaborador de logger opcional |
Contexto comercial
Sección titulada «Contexto comercial»La firma digital está disponible solo cuando nextpdf/premium (Pro) está instalado; el perfil que entrega este bundle es baseline B-B. Es una capacidad opcional de Pro; el bundle Core documentado aquí no necesita ningún cambio de código para adoptarla. Consulta </get-license/?intent=symfony-pro>.
Véase también
Sección titulada «Véase también»- /integrations/symfony/production-usage/ — seguridad de los workers y streaming.
- /integrations/symfony/configuration/ — las tablas de signature, tsa y servicios.
- /integrations/symfony/troubleshooting/ — diagnóstico de problemas de firma y de Messenger.
- /integrations/symfony/integration/ — referencia del cableado de extremo a extremo.