Sicurezza e operatività del pacchetto Laravel di NextPDF
In breve
Sezione intitolata “In breve”Il pacchetto applica un set fisso di header di risposta, sanifica i nomi dei file scaricati, convalida sul worker i percorsi di output della coda e incapsula le chiamate HTTP all’autorità di marcatura temporale in un client consapevole del rischio di falsificazione delle richieste. Questa pagina illustra il modello delle minacce e la configurazione di distribuzione richiesta per ciascun controllo.
Installazione
Sezione intitolata “Installazione”composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configPanoramica concettuale
Sezione intitolata “Panoramica concettuale”Il pacchetto integra un motore PDF in un framework web. Il confine di fiducia è rappresentato dalla richiesta HTTP e dal trasporto della coda. I controlli descritti di seguito riguardano la gestione delle risposte, i payload deserializzati dei job e le chiamate HTTP in uscita verso un’autorità di marcatura temporale.
Superficie dell’API — modello delle minacce
Sezione intitolata “Superficie dell’API — modello delle minacce”| Asset | Minaccia | Controllo in questo pacchetto | Configurazione di distribuzione richiesta |
|---|---|---|---|
| Risposta HTTP PDF | Sniffing del content-type, clickjacking, indicizzazione | Set fisso di header impostato da ogni factory PdfResponse generata | Nessuna; gli header non sono configurabili |
| Nome del file scaricato | Iniezione di header, path traversal in Content-Disposition | Il sanificatore dei nomi dei file rimuove separatori, caratteri di controllo e byte null | Nessuna; il sanificatore viene sempre eseguito |
| Percorso di output del job in coda | Scrittura arbitraria di file tramite payload serializzato manomesso | Percorso convalidato in handle() sul worker | Indirizzare l’output a un percorso di archiviazione controllato |
| HTTP TSA in uscita | Server-side request forgery, manomissione del testo in chiaro | Client HTTP consapevole del rischio di falsificazione delle richieste; HTTPS imposto a meno che non venga esplicitamente allentato | Mantenere tsa.allow_insecure_http = false; applicare il pinning SPKI |
| Stato condiviso del worker | Fuga di stato tra richieste nei worker a lunga durata | Registro dei font bloccato; cache delle immagini limitata; documento associato alla factory | Impostare preload_fonts; limitare la memoria a livello di container |
Hardening delle risposte
Sezione intitolata “Hardening delle risposte”Ogni factory PdfResponse imposta un set fisso di header:
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
Questi valori sono costanti in PdfResponse. Non sono configurabili. La suite di test del pacchetto verifica ogni header su ciascun metodo factory, incluse le varianti in streaming.
Il nome del file scaricato passa attraverso un sanificatore prima di raggiungere l’header Content-Disposition. Il sanificatore rimuove i separatori di percorso, i caratteri di controllo e i byte null, ed emette un parametro RFC 5987 filename*= per i nomi non ASCII. Un nome di file vuoto diventa document.pdf.
Convalida del payload della coda
Sezione intitolata “Convalida del payload della coda”GeneratePdfJob serializza una closure nel trasporto della coda. Il percorso di output viene convalidato all’interno di handle() sul worker, non al momento del dispatch. La convalida rifiuta:
- i byte null nel percorso,
- gli schemi degli stream wrapper (ad esempio
php://), - segmenti di path traversal
.., - qualsiasi percorso che non termini con
.pdf(senza distinzione tra maiuscole e minuscole).
Ogni rifiuto solleva InvalidArgumentException. La convalida viene eseguita al punto di consumo. Il payload serializzato in un trasporto Redis o database potrebbe essere alterato prima che il worker lo legga. Indirizzare il percorso di output a una directory di archiviazione controllata; non derivarlo da input di richiesta non convalidato.
HTTP in uscita verso un’autorità di marcatura temporale
Sezione intitolata “HTTP in uscita verso un’autorità di marcatura temporale”Quando è configurata un’autorità di marcatura temporale, il pacchetto associa un Psr\Http\Client\ClientInterface PSR-18. Un client PSR-18 invia una richiesta PSR-7 e restituisce una risposta PSR-7 (PSR-18 §2). Il client associato racchiude un client basato su curl con un livello consapevole del rischio di falsificazione delle richieste che impone HTTPS a meno che tsa.allow_insecure_http non sia esplicitamente impostato su true.
L’autorità di marcatura temporale è una funzionalità del piano Premium. Il pacchetto Core qui documentato associa il client HTTP e il collegamento del client di marcatura temporale; la firma vera e propria richiede nextpdf/premium. Questa pagina non documenta il comportamento dei baseline PAdES oltre il livello B-B; i baseline superiori sono fuori ambito.
Indicazioni operative per l’autorità di marcatura temporale:
- Mantenere
tsa.allow_insecure_httpimpostato sufalsein produzione. - Impostare
tsa.pinned_public_keyssugli hash SPKI SHA-256 in base64 del certificato dell’autorità di marcatura temporale (forma RFC 7469). - Mantenere
tsa.warn_on_key_rotationimpostato sutrueaffinché una modifica dello SPKI venga registrata prima della scadenza del certificato pinnato. - Ricavare
tsa.urlsolo da configurazione attendibile. Se un operatore può impostarlo da un’interfaccia di amministrazione, applicare regole di firewall in uscita o criteri DNS per ridurre l’esposizione al rischio di falsificazione delle richieste.
Logging
Sezione intitolata “Logging”Usare Psr\Log\LoggerInterface per la diagnostica. Passare un contesto strutturato, non stringhe interpolate. PSR-3 delega l’escaping dei segnaposto all’implementazione del logger e indica ai chiamanti di non eseguire il pre-escaping dei valori di contesto (PSR-3 §1.2). Registrare la classe dell’eccezione, non il messaggio né la traccia, per ridurre i dettagli interni nei log.
Esempio di codice — produzione
Sezione intitolata “Esempio di codice — produzione”<?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 ], ],];Casi limite e insidie
Sezione intitolata “Casi limite e insidie”- Il set di header di risposta è fisso. Le applicazioni che necessitano di una CSP diversa devono elaborare la risposta a posteriori, dopo che la factory l’ha restituita.
- La convalida del percorso viene eseguita sul worker. Un percorso errato supera
dispatch()e fallisce solo quando il job viene eseguito. tsa.allow_insecure_http = truerimuove l’imposizione di HTTPS e indebolisce l’affidabilità della marcatura temporale. Limitarlo allo sviluppo locale.- Il registro dei font viene bloccato dopo il warmup; un tentativo a runtime di registrare un font in un worker di lunga durata viene rifiutato per scelta progettuale.
Prestazioni
Sezione intitolata “Prestazioni”I controlli di sicurezza sono operazioni su stringhe e array a tempo costante e non aggiungono alcun costo misurabile per richiesta. Il costo operativo predominante è l’analisi dei font al primo utilizzo; precaricare i font all’avvio del worker per evitare la latenza alla prima richiesta.
Note sulla sicurezza
Sezione intitolata “Note sulla sicurezza”Questa pagina è il riferimento per il modello delle minacce del pacchetto. I controlli qui descritti sono applicati nel codice sorgente e verificati dalla suite di test. La configurazione di distribuzione a carico dell’operatore è indicata nella tabella del modello delle minacce e nei passaggi relativi all’autorità di marcatura temporale.
Conformità
Sezione intitolata “Conformità”| Dichiarazione | Fonte | Clausola | reference_id |
|---|---|---|---|
| Il client PSR-18 invia una richiesta PSR-7, restituisce una risposta PSR-7 | PSR-18 HTTP Client | §2 | |
| Il chiamante passa un contesto di log strutturato senza escaping | PSR-3 Logger | §1.2 |
Il pinning SPKI RFC 7469 è indicato come forma utilizzata dalla chiave di configurazione tsa.pinned_public_keys; il pacchetto utilizza i valori di pin forniti dall’operatore e non implementa direttamente l’RFC.
Contesto commerciale
Sezione intitolata “Contesto commerciale”La firma PAdES B-B e l’integrazione con l’autorità di marcatura temporale richiedono nextpdf/premium. Si tratta di una funzionalità Enterprise opzionale; il pacchetto Core qui documentato non richiede alcuna modifica al codice per adottarla. Vedere https://nextpdf.dev/get-license/?intent=laravel-signing.
Vedere anche
Sezione intitolata “Vedere anche”- /integrations/laravel/configuration/ — ogni chiave TSA, di firma e di coda
- /integrations/laravel/production-usage/ — pattern di DI e gestione degli errori
- /integrations/laravel/troubleshooting/ — perché i controlli sul percorso rifiutano l’input
- /integrations/laravel/boot-and-discovery/ — cicli di vita dei binding nei worker di lunga durata