Resumen de seguridad
TCPDF-Next está construido sobre una filosofía de diseño de seguridad primero. Cada componente, desde primitivas criptográficas hasta el parseo HTML, está diseñado para eliminar categorías completas de vulnerabilidades en lugar de parchalas después de su descubrimiento.
Filosofía de diseño de seguridad primero
La seguridad en TCPDF-Next no es una funcionalidad añadida encima de un código base legacy. Es una restricción arquitectónica que influyó en cada decisión de diseño desde el primer día:
- Denegar por defecto — La carga de recursos externos, las solicitudes de red y el acceso a archivos están bloqueados a menos que se permitan explícitamente.
- Fallar cerrado — Cuando no se puede realizar una verificación de seguridad (ej., responder OCSP inalcanzable), la operación falla en lugar de proceder de manera insegura.
- Defensa en profundidad — Múltiples capas independientes de protección aseguran que un solo bypass no comprometa el sistema.
- Superficie de ataque mínima — Cero dependencias Composer en runtime. Todas las operaciones criptográficas usan las extensiones integradas de PHP OpenSSL y Sodium.
Cifrado AES-256 (sin algoritmos legacy)
TCPDF-Next implementa exclusivamente cifrado AES-256 como se define en PDF 2.0 (ISO 32000-2, Revision 6). Todos los algoritmos legacy e inseguros son permanentemente rechazados:
| Algoritmo | Estado | Razón |
|---|---|---|
| AES-256-CBC | Soportado | Estándar PDF 2.0, sin ataques prácticos conocidos |
| RC4 (40-bit / 128-bit) | Prohibido | Cifrado de flujo con sesgos conocidos y ataques prácticos |
| AES-128 | Prohibido | Margen insuficiente para confidencialidad a largo plazo |
| DES / 3DES | No implementado | Vulnerabilidades de tamaño de bloque y longitud de clave |
| MD5 (para derivación de clave) | Prohibido | Ataques de colisión desde 2004 |
use YeeeFang\TcpdfNext\Encryption\EncryptionAlgorithm;
use YeeeFang\TcpdfNext\Encryption\Permissions;
$pdf->setEncryption()
->setAlgorithm(EncryptionAlgorithm::AES256)
->setUserPassword('reader-password')
->setOwnerPassword('admin-password')
->setPermissions(
Permissions::PRINT_HIGH_QUALITY
| Permissions::COPY
| Permissions::ACCESSIBILITY
)
->apply();Firmas digitales PAdES (B-B hasta B-LTA)
TCPDF-Next implementa el perfil PAdES Baseline completo (ETSI EN 319 142-1) para firmas digitales con niveles crecientes de validez a largo plazo:
| Nivel | Descripción | Período de validación |
|---|---|---|
| PAdES B-B | Firma CMS básica con certificado de firma | Validez del certificado (~1-3 años) |
| PAdES B-T | + Timestamp RFC 3161 de una TSA de confianza | Validez del certificado TSA (~10-15 años) |
| PAdES B-LT | + Document Security Store con datos OCSP/CRL | Vida útil de seguridad del algoritmo (~15-30 años) |
| PAdES B-LTA | + Archive timestamp para re-validación indefinida | Indefinido (con re-timestamping periódico) |
Para detalles de implementación, consulta Firmas PAdES B-LTA.
Protección SSRF con DNS pinning
Todas las solicitudes de red externas (obtención de imágenes, comunicación TSA, consultas OCSP) pasan por un cliente HTTP endurecido con protección SSRF integrada:
- DNS pinning — Las direcciones IP resueltas se validan antes de la conexión. Los rangos de red privada (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), loopback (127.0.0.0/8) y link-local (169.254.0.0/16) están bloqueados. - Restricción de protocolo — Solo
https://está permitido por defecto.http://simple se rechaza a menos que se permita explícitamente. - Allowlisting de dominios — Lista de dominios permitidos configurable para dominios externos permitidos.
- Seguimiento de redirecciones — Limitado a un máximo configurable (predeterminado: 3) con re-validación en cada salto.
Prevención de path traversal
Todas las operaciones de rutas de archivo se sanitizan para prevenir ataques de directory traversal:
- Los nombres de archivos embebidos se limpian de separadores de ruta y secuencias
... - Las rutas de archivos de fuentes se resuelven a rutas canónicas absolutas y se validan contra directorios permitidos.
- Las rutas de imágenes referenciadas en HTML se restringen a directorios explícitamente configurados via
ResourcePolicy.
#[\SensitiveParameter] en contraseñas y claves
Todos los parámetros de métodos que aceptan contraseñas, frases de paso, claves privadas o PINs están anotados con el atributo #[\SensitiveParameter] de PHP 8.2. Esto asegura que los valores sensibles se redacten automáticamente de stack traces, logs de errores y mensajes de excepción:
public function setUserPassword(
#[\SensitiveParameter] string $password
): self { /* ... */ }
public function setCertificate(
string $certificate,
#[\SensitiveParameter] string $privateKey,
#[\SensitiveParameter] string $passphrase = ''
): self { /* ... */ }#[\NoDiscard] en valores de retorno críticos
Los métodos que retornan resultados críticos para la seguridad (resultados de validación, verificación de firma) están anotados con #[\NoDiscard] para prevenir que los llamadores ignoren valores de retorno:
#[\NoDiscard]
public function validate(string $pdfPath): ValidationResult { /* ... */ }
#[\NoDiscard]
public function verify(): SignatureVerificationResult { /* ... */ }Ignorar estos valores de retorno produce una advertencia del compilador, capturando una clase común de bugs de seguridad en tiempo de desarrollo.
PHPStan Level 10 (cero errores, sin baseline)
Todo el código base pasa análisis estático PHPStan al nivel más estricto (Level 10) con cero errores y sin archivo baseline. Esto significa:
- Ninguna anotación
@phpstan-ignoreen todo el código base. - Ninguna categoría de error suprimida.
- Todos los tipos están completamente especificados, incluyendo generics y template types.
- Todas las rutas de código muerto están eliminadas.
100% declare(strict_types=1)
Cada archivo PHP en TCPDF-Next comienza con declare(strict_types=1). No hay excepciones. Esto elimina una clase completa de bugs de coerción de tipos que históricamente han llevado a vulnerabilidades de seguridad en aplicaciones PHP.
Consideraciones de cumplimiento OWASP
TCPDF-Next aborda las siguientes categorías OWASP relevantes para bibliotecas de generación de PDF:
| Categoría OWASP | Mitigación |
|---|---|
| A01 — Control de acceso roto | Permisos granulares de PDF, cifrado basado en certificados |
| A02 — Fallos criptográficos | Solo AES-256, sin algoritmos débiles, comparaciones en tiempo constante |
| A03 — Inyección | Sanitización HTML, prevención de path traversal, sin eval() |
| A05 — Configuración de seguridad incorrecta | Valores predeterminados seguros, políticas de recursos deny-by-default |
| A06 — Componentes vulnerables | Cero dependencias en runtime, crypto integrado via OpenSSL/Sodium |
| A07 — Fallos de autenticación | #[\SensitiveParameter], borrado seguro de memoria via sodium_memzero() |
| A10 — SSRF | DNS pinning, bloqueo de redes privadas, allowlisting de dominios |
Documentación de seguridad
Explora la documentación completa de seguridad:
- Mejores prácticas de seguridad — Validación de entrada, gestión de certificados, seguridad de despliegue
- Resumen de seguridad — Vectores de ataque de firmas PDF y mitigaciones