Contratos / Política de seguridad
De un vistazo
Sección titulada «De un vistazo»El dominio de políticas de seguridad agrupa tres contratos que deniegan de forma predeterminada: CryptoPolicyInterface controla la elección de algoritmos y claves, HtmlSecurityPolicyInterface restringe la superficie funcional de HTML y ExternalResourcePolicyInterface gobierna la carga de recursos remotos. Cada uno es un contrato, de modo que un despliegue puede suministrar una política más estricta sin hacer un fork.
Instalación
Sección titulada «Instalación»composer require nextpdf/core:^3Descripción conceptual
Sección titulada «Descripción conceptual»CryptoPolicyInterface es el punto de control de cifrado. El core la consulta antes de cualquier paso de firma, cifrado o hash. La comprobación cubre el hash, el OID de la firma, el cifrador y la fortaleza de la clave. El contrato también informa del hash mínimo y de un nombre de política para el registro de auditoría. Aplica un conjunto de reglas como FIPS 140-3 o eIDAS. El código de firma y cifrado permanece sin cambios. Cuando no se establece ninguna política, se permite cualquier algoritmo. En un sitio regulado se debe establecer una política explícita.
HtmlSecurityPolicyInterface opera en la capa de análisis de HTML. Se ejecuta antes de que el contenido llegue a cualquier renderer. Indica si se permite una etiqueta, un atributo, una propiedad CSS o un esquema de URL. También limita el tamaño de la entrada y la profundidad de anidamiento. Se combina con las políticas de transporte de cada renderer (Chrome, Cloudflare, Gotenberg), que establecen los límites de tamaño y los encabezados CSP. La política de HTML reduce la superficie de ataque de la capa de análisis. Una etiqueta eliminada nunca llega al diseño. Por lo tanto, un elemento inyectado no puede cambiar la salida. Cuando no se establece ninguna política, el valor predeterminado permite todo el conjunto de funciones.
ExternalResourcePolicyInterface indica si la pipeline de HTML puede obtener una fuente, una hoja de estilos o una imagen externa. También establece los límites para cada obtención. Su postura predeterminada es denegar todo. Cada opción está desactivada hasta que se activa. El contrato sigue el principio de privilegio mínimo. El HTML no confiable puede apuntar a una URL de un atacante. Controla la obtención de @font-face por esquema, tamaño y número de glifos. Controla @import por esquema, profundidad y tamaño total. Controla background-image mediante una lista de esquemas y una lista de permitidos de dominios con coincidencia exacta. Limita el tamaño de las URI de datos. También controla las referencias externas de SVG. El contrato establece que, en producción, siempre deben denegarse. Habilitan la falsificación de solicitudes y la inyección de scripts. La obtención abierta de URL es un vector de falsificación de solicitudes del lado del servidor. El control de acceso se elude modificando la URL, según el OWASP Top 10 2025. Los componentes deben provenir únicamente de fuentes oficiales a través de enlaces seguros.
Superficie de API
Sección titulada «Superficie de API»| Tipo | Clase | Miembros clave | Estabilidad | Desde |
|---|---|---|---|---|
CryptoPolicyInterface | interface | isHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName() | stable | 1.9.0 |
HtmlSecurityPolicyInterface | interface | isTagAllowed(), isAttributeAllowed(), isCssPropertyAllowed(), isUrlSchemeAllowed(), getMaxInputSize(), getMaxNestingDepth(), getName() | stable | 3.1.0 |
ExternalResourcePolicyInterface | interface | isFontFaceAllowed(), getAllowedFontSchemes(), getMaxFontFileSize(), getMaxFontGlyphs(), isImportAllowed(), getMaxImportDepth(), isBackgroundImageAllowed(), getAllowedImageDomains(), getMaxDataUrlSize(), isSvgExternalReferenceAllowed() | stable | 4.0.0 |
ExternalResourcePolicyInterface devuelve límites con tipos: tamaños positive-int, profundidad de importación int<1, 100> y listas de esquemas y dominios list<non-empty-string>. La implementación predeterminada deniega todas las capacidades.
Ejemplo de código — Inicio rápido
Sección titulada «Ejemplo de código — Inicio rápido»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\HtmlSecurityPolicyInterface;
/** * Decide whether a tag survives the policy. * * @param HtmlSecurityPolicyInterface $policy A core or custom policy. */function tagSurvives(HtmlSecurityPolicyInterface $policy, string $tag): bool{ return $policy->isTagAllowed($tag);}La función depende del contrato. Tanto una política restrictiva como la política predeterminada lo cumplen.
Ejemplo de código — Producción
Sección titulada «Ejemplo de código — Producción»<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;use NextPDF\Contracts\ExternalResourcePolicyInterface;use NextPDF\Contracts\HtmlSecurityPolicyInterface;use Psr\Log\LoggerInterface;
final readonly class UntrustedHtmlGate{ public function __construct( private HtmlSecurityPolicyInterface $htmlPolicy, private ExternalResourcePolicyInterface $resourcePolicy, private CryptoPolicyInterface $cryptoPolicy, private LoggerInterface $logger, ) {}
/** * Reject input that exceeds the configured limits before rendering. * * @param string $html Untrusted HTML markup. */ public function assertAcceptable(string $html): void { $maxInput = $this->htmlPolicy->getMaxInputSize();
if ($maxInput > 0 && \strlen($html) > $maxInput) { $this->logger->warning('HTML rejected: input over limit', [ 'policy' => $this->htmlPolicy->getName(), 'limit' => $maxInput, ]);
throw new \LengthException('HTML input exceeds policy limit.'); }
if ($this->resourcePolicy->isSvgExternalReferenceAllowed()) { $this->logger->error('Unsafe policy: SVG external references enabled.');
throw new \LogicException('SVG external references must be denied in production.'); } }}La compuerta aplica el límite de entrada y rechaza una política de recursos insegura antes de ejecutar la pipeline. Registra el nombre de la política para la auditoría y lanza una excepción específica.
Casos límite y trampas
Sección titulada «Casos límite y trampas»CryptoPolicyInterfacepermite cualquier algoritmo cuando no se establece ninguna política. El valor predeterminado abierto es una comodidad para el desarrollo, no una postura de producción. Se debe establecer una política explícita en cualquier despliegue regulado.HtmlSecurityPolicyInterface::getMaxInputSize()devuelve0para indicar ausencia de límite. Tratar0como «sin límite de política», no como «rechazar todo», y aplicar también un límite en la capa de transporte.ExternalResourcePolicyInterfacedeniega todo de forma predeterminada. Habilitar@font-faceobackground-imagesin establecer una lista de esquemas abre una superficie de falsificación de solicitudes; se debe establecer la lista de permitidos cuando se habilite una capacidad.- Una lista de permitidos de dominios vacía en
getAllowedImageDomains()significa que, una vez habilitadas las imágenes de fondo, se permiten todos los dominios. Una lista vacía no implica denegación; se deben suministrar dominios explícitos. isSvgExternalReferenceAllowed()debe devolverfalseen producción. El contrato lo documenta; una política que devuelvetruees un hallazgo, no una opción de configuración.
Rendimiento
Sección titulada «Rendimiento»Una comprobación de política es una llamada a un predicado: O(1), sin coste proporcional al tamaño de la entrada. La política se consulta por cada etiqueta, por cada atributo, por cada propiedad CSS y por cada URL durante el análisis. Un documento patológico multiplica el número de llamadas. Cada llamada se mantiene en tiempo constante. El performance_budget de 1500 ms de reloj y 64 MB de pico está dominado por el análisis y el renderizado, no por la evaluación de la política. Los límites de tamaño de entrada y de profundidad de anidamiento existen para acotar el coste del analizador. Una política estricta mejora el rendimiento en el peor caso al rechazar antes del diseño un documento de tamaño excesivo o con anidamiento profundo.
Notas de seguridad
Sección titulada «Notas de seguridad»Estos contratos son el perímetro defensivo del motor, por lo que el modelo de amenazas es explícito. La degradación de algoritmos se mitiga mediante CryptoPolicyInterface, que bloquea los hashes débiles y las claves cortas antes de cualquier operación. Las secuencias de comandos en sitios cruzados hacia PDF y la inyección de contenido se mitigan mediante HtmlSecurityPolicyInterface, que elimina las etiquetas, los atributos y el CSS no permitidos en la capa de análisis antes de que se ejecute el renderer. La falsificación de solicitudes del lado del servidor, las bombas de descompresión y las bombas de tamaño acumulado se mitigan mediante ExternalResourcePolicyInterface, que deniega todo de forma predeterminada y acota cada obtención por esquema, tamaño, profundidad y dominio. El agotamiento de recursos se mitiga mediante los límites de tamaño de entrada, profundidad de anidamiento, glifos de fuente y profundidad de importación. Como cada política es un contrato, un despliegue puede endurecer el perímetro sin hacer un fork del motor, y el nombre de la política se expone para el registro de auditoría. Tratar todo el HTML, todas las URL y todos los bytes de fuentes e imágenes como hostiles. Esta página está marcada como export_control_class: legal-review-required porque los contratos gobiernan la política criptográfica; la prosa parafrasea todas las fuentes normativas y no cita ninguna.
Conformidad
Sección titulada «Conformidad»| Afirmación | Estándar | Cláusula | Evidencia |
|---|---|---|---|
| El manejo de URL sin restricciones permite eludir el control de acceso modificando la URL, lo que la política de recursos externos mitiga mediante valores predeterminados de denegación total y una lista de permitidos de dominios con coincidencia exacta. | OWASP Top 10 2025 | A01 | |
| Los componentes externos deben obtenerse únicamente de fuentes oficiales a través de enlaces seguros, lo que la política aplica mediante listas de permitidos de esquemas. | OWASP Top 10 2025 | Cadena de suministro de software |
Ambos puntos están parafraseados a partir de las directrices de OWASP. El material de OWASP se referencia por cláusula; el motor no reproduce su texto.
Contexto comercial
Sección titulada «Contexto comercial»El core define y congela los tres contratos de política, y suministra valores predeterminados permisivos para el desarrollo junto con una política de recursos estricta de denegación total por defecto. La edición Enterprise suministra un perfil FIPS 140-3 detrás de CryptoPolicyInterface, de modo que un despliegue regulado obtiene una postura de algoritmos validada sin cambiar el código de firma o cifrado. La superficie del contrato es idéntica en todas las ediciones. La diferencia es la implementación de política que inyecta cada despliegue.
Véase también
Sección titulada «Véase también»- Contratos: 41 interfaces públicas (SPI) — descripción general de SPI y niveles de estabilidad.
- Contratos / Firma —
CryptoPolicyInterfaceaplicado a la firma. - Contratos / Documento — los puntos de entrada
writeHtml()eimage()controlados por estas políticas. - Seguridad — la superficie de cifrado que la política de cifrado restringe.
- HTML — la pipeline de análisis que las políticas de HTML y de recursos protegen.
- Auditoría — registro de auditoría del nombre de la política.