Sécurité et exploitation du package NextPDF pour Laravel
Le package applique un jeu fixe d’en-têtes de réponse, assainit les noms de fichier proposés au téléchargement, valide les chemins de sortie de la file d’attente sur le worker et fait transiter le trafic HTTP vers l’autorité d’horodatage par un client tenant compte des falsifications de requête. Cette page énonce le modèle de menace et la configuration de déploiement exigée par chaque contrôle.
Installation
Section intitulée « Installation »composer require nextpdf/laravelphp artisan vendor:publish --tag=nextpdf-configVue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Ce package adapte un moteur PDF à un framework web. La frontière de confiance se situe au niveau de la requête HTTP et du transport de la file d’attente. Les contrôles ci-dessous couvrent la gestion des réponses, les charges utiles de tâches désérialisées et le trafic HTTP sortant vers une autorité d’horodatage.
Surface d’API — modèle de menace
Section intitulée « Surface d’API — modèle de menace »| Actif | Menace | Contrôle dans ce package | Configuration de déploiement requise |
|---|---|---|---|
| Réponse HTTP du PDF | Détection du type de contenu, clickjacking, indexation | Jeu fixe d’en-têtes appliqué par chaque fabrique PdfResponse invoquée | Aucune ; les en-têtes ne sont pas configurables |
| Nom de fichier de téléchargement | Injection d’en-tête, traversée de chemin dans Content-Disposition | L’assainisseur de nom de fichier supprime les séparateurs, les caractères de contrôle et les octets nuls | Aucune ; l’assainisseur s’exécute toujours |
| Chemin de sortie de la tâche de file d’attente | Écriture de fichier arbitraire via une charge utile sérialisée altérée | Chemin validé dans handle() sur le worker | Dirige la sortie vers un chemin de stockage maîtrisé |
| Trafic HTTP sortant vers la TSA | Falsification de requête côté serveur, altération en clair | Client HTTP tenant compte des falsifications de requête ; HTTPS imposé sauf relâchement explicite | Conserve tsa.allow_insecure_http = false ; épingle la SPKI |
| État partagé du worker | Fuite d’état entre requêtes dans les workers à longue durée de vie | Registre de polices verrouillé ; cache d’images borné ; document lié à la fabrique | Définis preload_fonts ; borne la mémoire au niveau du conteneur |
Durcissement des réponses
Section intitulée « Durcissement des réponses »Chaque fabrique PdfResponse applique un jeu fixe d’en-têtes :
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
Ces valeurs sont des constantes dans PdfResponse. Elles ne sont pas configurables. La suite de tests du package vérifie chaque en-tête sur chaque méthode de fabrique, y compris les variantes en flux.
Le nom de fichier proposé au téléchargement passe par un assainisseur avant d’atteindre l’en-tête Content-Disposition. L’assainisseur retire les séparateurs de chemin, les caractères de contrôle et les octets nuls, et émet un paramètre RFC 5987 filename*= pour les noms non ASCII. Un nom de fichier vide devient document.pdf.
Validation des charges utiles de file d’attente
Section intitulée « Validation des charges utiles de file d’attente »GeneratePdfJob sérialise une closure dans le transport de la file d’attente. Le chemin de sortie est validé dans handle() sur le worker, et non au moment de la répartition. La validation rejette :
- les octets nuls dans le chemin,
- les schémas de wrapper de flux (par exemple
php://), - les segments de traversée de chemin
.., - tout chemin qui ne se termine pas par
.pdf(insensible à la casse).
Chaque rejet lève InvalidArgumentException. La validation s’exécute au point de consommation. La charge utile sérialisée sur un transport Redis ou en base de données pourrait être altérée avant que le worker ne la lise. Dirige le chemin de sortie vers un répertoire de stockage maîtrisé ; ne le dérive pas d’une entrée de requête non validée.
Trafic HTTP sortant vers une autorité d’horodatage
Section intitulée « Trafic HTTP sortant vers une autorité d’horodatage »Quand une autorité d’horodatage est configurée, le package lie un Psr\Http\Client\ClientInterface PSR-18. Un client PSR-18 envoie une requête PSR-7 et renvoie une réponse PSR-7 (PSR-18 §2). Le client lié enveloppe un client basé sur curl dans une couche tenant compte des falsifications de requête, qui impose HTTPS sauf si tsa.allow_insecure_http vaut explicitement true.
L’autorité d’horodatage est une fonctionnalité du niveau Premium. Le package Core documenté ici lie le client HTTP et le câblage du client d’horodatage ; la signature elle-même requiert nextpdf/premium. Cette page ne documente pas le comportement de la ligne de base PAdES au-delà de B-B ; les lignes de base supérieures sont hors périmètre.
Conseils d’exploitation pour l’autorité d’horodatage :
- Conserve
tsa.allow_insecure_httpdéfini surfalseen production. - Définis
tsa.pinned_public_keyssur les empreintes SPKI SHA-256 en base64 du certificat de l’autorité d’horodatage (forme RFC 7469). - Conserve
tsa.warn_on_key_rotationdéfini surtruepour qu’une SPKI modifiée soit journalisée avant l’expiration du certificat épinglé. - Ne définis
tsa.urlqu’à partir d’une configuration de confiance. Si un opérateur peut le définir depuis une interface d’administration, applique une politique de pare-feu de sortie ou de DNS pour réduire l’exposition aux falsifications de requête.
Journalisation
Section intitulée « Journalisation »Utilise Psr\Log\LoggerInterface pour les diagnostics. Passe un contexte structuré, et non des chaînes interpolées. PSR-3 laisse l’échappement des espaces réservés à l’implémentation du logger et demande aux appelants de ne pas pré-échapper les valeurs de contexte (PSR-3 §1.2). Journalise la classe de l’exception, pas son message ni sa trace, afin de réduire le niveau de détail interne dans les journaux.
Exemple de code — Production
Section intitulée « Exemple de code — Production »<?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 ], ],];Cas limites et pièges
Section intitulée « Cas limites et pièges »- Le jeu d’en-têtes de réponse est figé. Les applications qui ont besoin d’une CSP différente doivent post-traiter la réponse après que la fabrique l’a renvoyée.
- La validation du chemin s’exécute sur le worker. Un mauvais chemin passe
dispatch()et n’échoue qu’au moment où la tâche s’exécute. tsa.allow_insecure_http = truesupprime l’imposition de HTTPS et affaiblit la confiance dans l’horodatage. Restreins-le au développement local.- Le registre de polices est verrouillé après le préchauffage ; une tentative d’enregistrer une police à l’exécution dans un worker à longue durée de vie est rejetée par conception.
Performances
Section intitulée « Performances »Les contrôles de sécurité sont des opérations sur chaînes et tableaux à temps constant et n’ajoutent aucun coût mesurable par requête. Le coût d’exploitation dominant est l’analyse des polices à la première utilisation ; précharge les polices au démarrage du worker pour éviter la latence de la première requête.
Notes de sécurité
Section intitulée « Notes de sécurité »Cette page est la référence du modèle de menace pour le package. Les contrôles décrits ici sont appliqués dans le code source et vérifiés par la suite de tests. La configuration de déploiement que l’opérateur doit fournir est indiquée dans le tableau du modèle de menace et dans les étapes relatives à l’autorité d’horodatage.
Conformité
Section intitulée « Conformité »| Affirmation | Source | Clause | reference_id |
|---|---|---|---|
| Le client PSR-18 envoie une requête PSR-7, renvoie une réponse PSR-7 | Client HTTP PSR-18 | §2 | |
| L’appelant passe un contexte de journalisation structuré non échappé | Logger PSR-3 | §1.2 |
L’épinglage SPKI RFC 7469 est mentionné comme la forme utilisée par la clé de configuration tsa.pinned_public_keys ; le package consomme les valeurs d’épingle fournies par l’opérateur et n’implémente pas la RFC lui-même.
Contexte commercial
Section intitulée « Contexte commercial »La signature PAdES B-B et l’intégration de l’autorité d’horodatage requièrent nextpdf/premium. Il s’agit d’une fonctionnalité Enterprise optionnelle ; le package Core documenté ici n’a besoin d’aucune modification de code pour l’adopter. Voir https://nextpdf.dev/get-license/?intent=laravel-signing.
Voir aussi
Section intitulée « Voir aussi »- /integrations/laravel/configuration/ — chaque clé de TSA, de signature et de file d’attente
- /integrations/laravel/production-usage/ — modèles d’injection de dépendances et de gestion des erreurs
- /integrations/laravel/troubleshooting/ — pourquoi les vérifications de chemin rejettent l’entrée
- /integrations/laravel/boot-and-discovery/ — durées de vie des liaisons dans les workers à longue durée de vie