Salta ai contenuti

Contratti / Criteri di sicurezza

Il dominio dei criteri di sicurezza comprende tre contratti la cui impostazione predefinita è la negazione: CryptoPolicyInterface regola le scelte relative ad algoritmi e chiavi, HtmlSecurityPolicyInterface limita la superficie delle funzionalità HTML e ExternalResourcePolicyInterface governa il caricamento delle risorse remote. Ciascuno è un contratto, quindi una distribuzione può fornire un criterio più restrittivo senza creare un fork.

Terminal window
composer require nextpdf/core:^3

CryptoPolicyInterface è il punto di controllo crittografico. Core lo interroga prima di qualsiasi operazione di firma, cifratura o hashing. Il controllo copre hash, OID della firma, cifrario e robustezza della chiave. Il contratto espone inoltre l’hash minimo e un nome del criterio per il log di controllo. Permette di applicare un set di regole come FIPS 140-3 o eIDAS. Il codice di firma e cifratura non cambia. Quando non è impostato alcun criterio, ogni algoritmo è consentito. Un sito soggetto a normativa deve impostare un criterio esplicito.

HtmlSecurityPolicyInterface opera durante il parsing HTML. Viene eseguito prima che il contenuto raggiunga qualsiasi renderer. Stabilisce se un tag, un attributo, una proprietà CSS o uno schema URL è consentito. Limita inoltre la dimensione dell’input e la profondità di annidamento. Si integra con i criteri di trasporto specifici per renderer (Chrome, Cloudflare, Gotenberg), che impostano i limiti di dimensione e le intestazioni CSP. Il criterio HTML riduce la superficie di attacco già in fase di parsing. Un tag rimosso non raggiunge mai l’impaginazione. Un elemento iniettato non può quindi modificare l’output. Quando non è impostato alcun criterio, l’impostazione predefinita consente l’intero set di funzionalità.

ExternalResourcePolicyInterface stabilisce se la pipeline HTML può recuperare un font, un foglio di stile o un’immagine esterni. Definisce inoltre i limiti per ogni recupero. La sua impostazione predefinita è negare tutto. Ogni opzione resta disattivata finché non viene abilitata. Il contratto applica il principio del privilegio minimo. L’HTML non attendibile può puntare all’URL di un utente malintenzionato. Regola il recupero di @font-face in base a schema, dimensione e numero di glifi. Regola @import in base a schema, profondità e dimensione totale. Regola background-image tramite un elenco di schemi e un elenco di domini consentiti a corrispondenza esatta. Limita la dimensione dei data-URI. Regola inoltre i riferimenti esterni SVG. Il contratto stabilisce che la produzione deve sempre negarli. Tali riferimenti consentono il request forgery e l’iniezione di script. Il recupero aperto di URL è un percorso di server-side request forgery. Il controllo degli accessi viene aggirato modificando l’URL, secondo OWASP Top 10 2025. I componenti devono provenire esclusivamente da fonti ufficiali tramite collegamenti sicuri.

TipoGenereMembri principaliStabilitàA partire da
CryptoPolicyInterfaceinterfacciaisHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName()stabile1.9.0
HtmlSecurityPolicyInterfaceinterfacciaisTagAllowed(), isAttributeAllowed(), isCssPropertyAllowed(), isUrlSchemeAllowed(), getMaxInputSize(), getMaxNestingDepth(), getName()stabile3.1.0
ExternalResourcePolicyInterfaceinterfacciaisFontFaceAllowed(), getAllowedFontSchemes(), getMaxFontFileSize(), getMaxFontGlyphs(), isImportAllowed(), getMaxImportDepth(), isBackgroundImageAllowed(), getAllowedImageDomains(), getMaxDataUrlSize(), isSvgExternalReferenceAllowed()stabile4.0.0

ExternalResourcePolicyInterface restituisce limiti tipizzati: dimensioni positive-int, profondità di importazione int<1, 100> ed elenchi di schemi e domini list<non-empty-string>. L’implementazione predefinita nega ogni capacità.

examples/contracts/security-policy-quickstart.php
<?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 funzione dipende dal contratto. La soddisfano sia un criterio restrittivo sia il criterio predefinito.

examples/contracts/security-policy-production.php
<?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.');
}
}
}

Il gate applica il limite di input e rifiuta un criterio per le risorse non sicuro prima dell’esecuzione della pipeline. Registra il nome del criterio a fini di controllo e solleva un’eccezione specifica.

  • CryptoPolicyInterface consente qualsiasi algoritmo quando non è impostato alcun criterio. L’impostazione predefinita aperta è pensata per lo sviluppo, non per la produzione. Impostare un criterio esplicito in qualsiasi distribuzione soggetta a normativa.
  • HtmlSecurityPolicyInterface::getMaxInputSize() restituisce 0 per indicare un valore illimitato. Considerare 0 come «nessun limite di criterio», non «rifiuta tutto», e applicare anche un limite a livello di trasporto.
  • ExternalResourcePolicyInterface nega tutto per impostazione predefinita. L’abilitazione di @font-face o background-image senza impostare un elenco di schemi apre una superficie di request forgery; impostare l’elenco dei valori consentiti quando si abilita una capacità.
  • Un elenco di domini consentiti vuoto su getAllowedImageDomains() significa che tutti i domini sono consentiti una volta abilitate le immagini di sfondo. Un elenco vuoto non equivale a un divieto; fornire domini espliciti.
  • isSvgExternalReferenceAllowed() dovrebbe restituire false in produzione. Il contratto lo documenta; un criterio che restituisce true è un segnale, non una scelta di configurazione.

Un controllo del criterio consiste in una chiamata a un predicato: O(1), senza costi proporzionali all’input. Il criterio viene consultato per ogni tag, attributo, proprietà CSS e URL durante il parsing. Un documento patologico moltiplica il numero di chiamate, ma ogni chiamata resta a tempo costante. Il performance_budget di 1500 ms di wall time e 64 MB di picco è dominato da parsing e rendering, non dalla valutazione del criterio. I limiti sulla dimensione dell’input e sulla profondità di annidamento servono a delimitare il costo del parser stesso. Un criterio rigoroso migliora le prestazioni nel caso peggiore, rifiutando un documento sovradimensionato o profondamente annidato prima dell’impaginazione.

Questi contratti costituiscono il perimetro difensivo del motore, quindi il modello di minaccia è esplicito. Il downgrade degli algoritmi è mitigato da CryptoPolicyInterface, che blocca hash deboli e chiavi corte prima di qualsiasi operazione. Il cross-site scripting-to-PDF e l’iniezione di contenuto sono mitigati da HtmlSecurityPolicyInterface, che rimuove tag, attributi e CSS non consentiti a livello di parsing, prima dell’esecuzione del renderer. Il server-side request forgery, le bombe di decompressione e le bombe di dimensione cumulativa sono mitigati da ExternalResourcePolicyInterface, che per impostazione predefinita nega tutto e delimita ogni recupero in base a schema, dimensione, profondità e dominio. L’esaurimento delle risorse è mitigato dai limiti su dimensione dell’input, profondità di annidamento, glifi dei font e profondità di importazione. Poiché ogni criterio è un contratto, una distribuzione rafforza il perimetro senza creare un fork del motore e il nome del criterio viene esposto per la registrazione di controllo. Considerare ostili tutto l’HTML, tutti gli URL e tutti i byte dei font e delle immagini. Questa pagina è contrassegnata come export_control_class: legal-review-required perché i contratti governano criteri crittografici; il testo parafrasa tutte le fonti normative e non ne cita alcuna testualmente.

AsserzioneStandardClausolaEvidenza
La gestione non vincolata degli URL consente di aggirare il controllo degli accessi modificando l’URL; il criterio per le risorse esterne mitiga il rischio con impostazioni predefinite che negano tutto e con un elenco di domini consentiti a corrispondenza esatta.OWASP Top 10 2025A01
I componenti esterni devono essere ottenuti esclusivamente da fonti ufficiali tramite collegamenti sicuri; il criterio lo impone tramite elenchi di schemi consentiti.OWASP Top 10 2025Catena di fornitura del software

Entrambi i punti sono parafrasati dalle linee guida OWASP. Il materiale OWASP è citato a livello di clausola; il motore non ne riproduce il testo.

Core definisce e congela i tre contratti dei criteri; fornisce impostazioni predefinite permissive per lo sviluppo e impostazioni predefinite rigorose per il criterio per le risorse, che nega tutto. L’edizione Enterprise fornisce un profilo FIPS 140-3 tramite CryptoPolicyInterface, in modo che una distribuzione soggetta a normativa ottenga una configurazione di algoritmi convalidata senza modificare il codice di firma o di cifratura. La superficie dei contratti è identica in tutte le edizioni. La differenza risiede nell’implementazione del criterio iniettata dalla distribuzione.

  • Contratti: 41 interfacce pubbliche (SPI) — panoramica dell’SPI e dei livelli di stabilità.
  • Contratti / FirmaCryptoPolicyInterface applicato alla firma.
  • Contratti / Documento — i punti di ingresso writeHtml() e image() regolati da questi criteri.
  • Sicurezza — la superficie di cifratura che il criterio di crittografia vincola.
  • HTML — la pipeline di parsing protetta dai criteri HTML e per le risorse.
  • Audit — registrazione del nome del criterio a fini di controllo.