Seguridad y operaciones del paquete Laravel de NextPDF
De un vistazo
Sección titulada «De un vistazo»El paquete aplica un conjunto fijo de encabezados de respuesta, sanea los nombres de archivo de descarga, valida en el worker las rutas de salida de la cola y encapsula el HTTP de la autoridad de marca de tiempo mediante un cliente con protección frente a la falsificación de solicitudes. Esta página presenta el modelo de amenazas y la configuración de despliegue que requiere cada control.
Instalación
Sección titulada «Instalación»composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configPanorama conceptual
Sección titulada «Panorama conceptual»El paquete integra un motor PDF en un framework web. El límite de confianza está en la solicitud HTTP y en el transporte de la cola. Los controles que se describen a continuación abordan el manejo de las respuestas, las cargas útiles deserializadas de los jobs y el HTTP saliente hacia una autoridad de marca de tiempo.
Superficie de la API — modelo de amenazas
Sección titulada «Superficie de la API — modelo de amenazas»| Activo | Amenaza | Control en este paquete | Configuración de despliegue requerida |
|---|---|---|---|
| Respuesta HTTP del PDF | Inferencia del tipo de contenido, clickjacking, indexación | Conjunto fijo de encabezados en cada factory de PdfResponse | Ninguna; los encabezados no son configurables |
| Nombre de archivo de descarga | Inyección de encabezados, path traversal en Content-Disposition | El saneador de nombres de archivo elimina separadores, caracteres de control y bytes nulos | Ninguna; el saneador siempre se ejecuta |
| Ruta de salida del job de la cola | Escritura arbitraria de archivos mediante una carga útil serializada manipulada | Ruta validada en handle() en el worker | Dirigir la salida hacia una ruta de almacenamiento controlada |
| HTTP saliente hacia la TSA | Falsificación de solicitudes del lado del servidor, manipulación en texto plano | Cliente HTTP con protección frente a la falsificación de solicitudes; HTTPS obligatorio salvo que se relaje explícitamente | Mantener tsa.allow_insecure_http = false; fijar la SPKI |
| Estado compartido del worker | Fuga de estado entre solicitudes en workers de larga duración | Registro de fuentes bloqueado; caché de imágenes acotada; documento ligado al factory | Establecer preload_fonts; acotar la memoria en el contenedor |
Endurecimiento de las respuestas
Sección titulada «Endurecimiento de las respuestas»Cada factory de PdfResponse establece un conjunto fijo de encabezados:
Cache-Control: private, max-age=0, must-revalidatePragma: publicX-Content-Type-Options: nosniffX-Frame-Options: DENYContent-Security-Policy: default-src 'none'X-Robots-Tag: noindex, nofollowReferrer-Policy: no-referrer
Estos valores son constantes en PdfResponse. No son configurables. La suite de pruebas del paquete verifica cada encabezado en cada método factory, incluidas las variantes de streaming.
El nombre de archivo de descarga se procesa con un saneador antes de llegar al encabezado Content-Disposition. El saneador elimina separadores de ruta, caracteres de control y bytes nulos, y emite un parámetro RFC 5987 filename*= para los nombres no ASCII. Un nombre de archivo vacío se convierte en document.pdf.
Validación de la carga útil de la cola
Sección titulada «Validación de la carga útil de la cola»GeneratePdfJob serializa un closure a través del transporte de la cola. La ruta de salida se valida dentro de handle() en el worker, no durante el despacho. La validación rechaza:
- bytes nulos en la ruta,
- los esquemas de stream-wrapper (por ejemplo,
php://), - los segmentos de path traversal
.., - cualquier ruta que no termine en
.pdf(sin distinguir mayúsculas y minúsculas).
Cada rechazo lanza InvalidArgumentException. La validación se ejecuta en el punto de consumo. La carga útil serializada en un transporte de Redis o de base de datos podría alterarse antes de que el worker la lea. La ruta de salida debe dirigirse hacia un directorio de almacenamiento controlado; no debe derivarse de la entrada de solicitud sin validar.
HTTP saliente hacia una autoridad de marca de tiempo
Sección titulada «HTTP saliente hacia una autoridad de marca de tiempo»Cuando se configura una autoridad de marca de tiempo, el paquete vincula un Psr\Http\Client\ClientInterface PSR-18. Un cliente PSR-18 envía una solicitud PSR-7 y devuelve una respuesta PSR-7 (PSR-18 §2). El cliente vinculado envuelve un cliente basado en curl con una capa con protección frente a la falsificación de solicitudes que obliga a usar HTTPS salvo que tsa.allow_insecure_http sea explícitamente verdadero.
La autoridad de marca de tiempo es una capacidad del nivel Premium. El paquete Core que se documenta aquí vincula el cliente HTTP y el cableado del cliente de marca de tiempo; la firma propiamente dicha requiere nextpdf/premium. Esta página no documenta el comportamiento de la línea base PAdES más allá de B-B; las líneas base superiores quedan fuera del alcance.
Guía operativa para la autoridad de marca de tiempo:
- Mantener
tsa.allow_insecure_httpcon el valorfalseen producción. - Establecer
tsa.pinned_public_keyscon los hashes SPKI SHA-256 en base64 del certificado de la autoridad de marca de tiempo (forma RFC 7469). - Mantener
tsa.warn_on_key_rotationcon el valortruepara que una SPKI modificada quede registrada antes de que el certificado fijado caduque. - Tomar
tsa.urlúnicamente de configuración de confianza. Si un operador puede establecerla desde una superficie de administración, aplicar una política de firewall de egreso o de DNS para reducir la exposición a la falsificación de solicitudes.
Registro de eventos
Sección titulada «Registro de eventos»Usar Psr\Log\LoggerInterface para los diagnósticos. Pasar contexto estructurado, no cadenas interpoladas. PSR-3 delega el escape de los marcadores de posición en la implementación del logger e indica a quienes lo invocan que no preescapen los valores de contexto (PSR-3 §1.2). Registrar la clase de la excepción, no el mensaje ni la traza, para reducir el detalle interno en los registros.
Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»<?php
declare(strict_types=1);
// .env — production timestamp-authority hardening// NEXTPDF_TSA_URL=https://tsa.example.test// NEXTPDF_TSA_ALLOW_INSECURE_HTTP=false// NEXTPDF_TSA_WARN_ROTATION=true
return [ 'tsa' => [ 'url' => env('NEXTPDF_TSA_URL'), 'allow_insecure_http' => env('NEXTPDF_TSA_ALLOW_INSECURE_HTTP', false), 'warn_on_key_rotation' => env('NEXTPDF_TSA_WARN_ROTATION', true), 'pinned_public_keys' => [ // base64 SHA-256 SPKI hashes of the TSA certificate ], ],];Casos límite y trampas
Sección titulada «Casos límite y trampas»- El conjunto de encabezados de respuesta es fijo. Las aplicaciones que necesiten una CSP diferente deben posprocesar la respuesta después de que el factory la devuelva.
- La validación de la ruta se ejecuta en el worker. Una ruta incorrecta pasa
dispatch()y solo falla cuando el job se ejecuta. tsa.allow_insecure_http = trueelimina la obligatoriedad de HTTPS y debilita la confianza en la marca de tiempo. Restringirlo al desarrollo local.- El registro de fuentes queda bloqueado después del calentamiento; un intento de registrar una fuente en tiempo de ejecución dentro de un worker de larga duración se rechaza por diseño.
Rendimiento
Sección titulada «Rendimiento»Los controles de seguridad son operaciones de cadenas y arreglos en tiempo constante y no añaden ningún costo medible por solicitud. El costo operativo dominante es el análisis de las fuentes en el primer uso; precargar las fuentes al arrancar el worker para evitar la latencia en la primera solicitud.
Notas de seguridad
Sección titulada «Notas de seguridad»Esta página es la referencia del modelo de amenazas del paquete. Los controles que se describen aquí se aplican en el código fuente y los verifica la suite de pruebas. La configuración de despliegue que el operador debe aportar se señala en la tabla del modelo de amenazas y en los pasos de la autoridad de marca de tiempo.
Conformidad
Sección titulada «Conformidad»| Afirmación | Fuente | Cláusula | reference_id |
|---|---|---|---|
| El cliente PSR-18 envía una solicitud PSR-7 y devuelve una respuesta PSR-7 | Cliente HTTP PSR-18 | §2 | |
| Quien invoca pasa contexto de registro estructurado sin escapar | Logger PSR-3 | §1.2 |
El fijado de SPKI de RFC 7469 se nombra como la forma que usa la clave de configuración tsa.pinned_public_keys; el paquete consume los valores de fijado aportados por el operador y no implementa la RFC propiamente dicha.
Contexto comercial
Sección titulada «Contexto comercial»La firma PAdES B-B y la integración con la autoridad de marca de tiempo requieren nextpdf/premium. Es una capacidad Enterprise opcional; el paquete Core que se documenta aquí no necesita ningún cambio de código para adoptarla. Consultar https://nextpdf.dev/get-license/?intent=laravel-signing.
Véase también
Sección titulada «Véase también»- /integrations/laravel/configuration/ — cada clave de TSA, de firma y de la cola
- /integrations/laravel/production-usage/ — patrones de DI y de manejo de errores
- /integrations/laravel/troubleshooting/ — por qué las comprobaciones de ruta rechazan la entrada
- /integrations/laravel/boot-and-discovery/ — tiempos de vida de los bindings en workers de larga duración