Zum Inhalt springen

Sicherheit und Betrieb des NextPDF-Laravel-Pakets

Das Paket setzt einen festen Satz von Antwortheadern, bereinigt Download-Dateinamen, validiert die Ausgabepfade von Queue-Jobs auf dem Worker und kapselt den HTTP-Verkehr zur Zeitstempelinstanz über einen gegen Request Forgery gehärteten Client. Diese Seite beschreibt das Bedrohungsmodell und die Deployment-Konfiguration, die jede Kontrolle erfordert.

Terminal-Fenster
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Das Paket bindet eine PDF-Engine in ein Web-Framework ein. Die Vertrauensgrenze verläuft bei der HTTP-Anfrage und beim Queue-Transport. Die folgenden Kontrollen betreffen die Antwortverarbeitung, deserialisierte Job-Nutzlasten und ausgehenden HTTP-Verkehr zu einer Zeitstempelinstanz.

AssetBedrohungKontrolle in diesem PaketErforderliche Deployment-Konfiguration
PDF-HTTP-AntwortContent-Type-Sniffing, Clickjacking, IndizierungFester Headersatz für jede PdfResponse-FactoryKeine; die Header sind nicht konfigurierbar
Download-DateinameHeader-Injection, Path Traversal in Content-DispositionDer Dateinamenbereiniger entfernt Trennzeichen, Steuerzeichen und Null-BytesKeine; der Bereiniger läuft immer
Ausgabepfad des Queue-JobsBeliebiger Dateischreibzugriff über eine manipulierte serialisierte NutzlastPfadvalidierung in handle() auf dem WorkerAusgabe in einen kontrollierten Storage-Pfad leiten
Ausgehender TSA-HTTP-VerkehrServer-Side Request Forgery, KlartextmanipulationGegen Request Forgery gehärteter HTTP-Client; HTTPS erzwungen, sofern nicht ausdrücklich gelockertBelassen Sie tsa.allow_insecure_http = false; SPKI pinnen
Geteilter Worker-ZustandZustandsleck zwischen Anfragen in langlebigen WorkernGesperrte Fontregistry; begrenzter Bildcache; an die Factory gebundenes DokumentSetzen Sie preload_fonts; Speicher am Container begrenzen

Jede PdfResponse-Factory setzt einen festen Headersatz:

  • Cache-Control: private, max-age=0, must-revalidate
  • Pragma: public
  • X-Content-Type-Options: nosniff
  • X-Frame-Options: DENY
  • Content-Security-Policy: default-src 'none'
  • X-Robots-Tag: noindex, nofollow
  • Referrer-Policy: no-referrer

Diese Werte sind Konstanten in PdfResponse. Sie sind nicht konfigurierbar. Die Testsuite des Pakets prüft jeden Header bei jeder Factory-Methode, einschließlich der gestreamten Varianten.

Der Download-Dateiname wird bereinigt, bevor er den Content-Disposition-Header erreicht. Der Bereiniger entfernt Pfadtrennzeichen, Steuerzeichen und Null-Bytes und gibt für Nicht-ASCII-Namen einen RFC 5987-filename*=-Parameter aus. Ein leerer Dateiname wird zu document.pdf.

GeneratePdfJob serialisiert eine Closure für den Queue-Transport. Der Ausgabepfad wird innerhalb von handle() auf dem Worker validiert, nicht beim Dispatch. Die Validierung lehnt ab:

  • Null-Bytes im Pfad,
  • Stream-Wrapper-Schemata (zum Beispiel php://),
  • ..-Segmente für Path Traversal,
  • jeden Pfad, der nicht auf .pdf endet (Groß-/Kleinschreibung wird ignoriert).

Jede Ablehnung wirft InvalidArgumentException. Die Validierung läuft zum Zeitpunkt der Verwendung. Die serialisierte Nutzlast auf einem Redis- oder Datenbank-Transport könnte verändert werden, bevor der Worker sie liest. Leiten Sie den Ausgabepfad in ein kontrolliertes Storage-Verzeichnis; leiten Sie ihn nicht aus nicht validierter Anfrageeingabe ab.

Ausgehender HTTP-Verkehr zu einer Zeitstempelinstanz

Abschnitt betitelt „Ausgehender HTTP-Verkehr zu einer Zeitstempelinstanz“

Wenn eine Zeitstempelinstanz konfiguriert ist, bindet das Paket ein PSR-18-Psr\Http\Client\ClientInterface. Ein PSR-18-Client sendet eine PSR-7-Anfrage und gibt eine PSR-7-Antwort zurück (PSR-18 §2). Der gebundene Client kapselt einen curl-basierten Client mit einer gegen Request Forgery gehärteten Schicht und erzwingt HTTPS, sofern tsa.allow_insecure_http nicht ausdrücklich auf true steht.

Die Zeitstempelinstanz ist eine Funktion der Premium-Stufe. Das hier dokumentierte Core-Paket bindet den HTTP-Client und die Verdrahtung des Zeitstempel-Clients ein; das Signieren selbst erfordert nextpdf/premium. Diese Seite dokumentiert kein PAdES-Baseline-Verhalten über B-B hinaus; höhere Baselines liegen außerhalb des Umfangs.

Betriebshinweise zur Zeitstempelinstanz:

  1. Belassen Sie tsa.allow_insecure_http in der Produktion auf false.
  2. Setzen Sie tsa.pinned_public_keys auf die Base64-SHA-256-SPKI-Hashes des Zertifikats der Zeitstempelinstanz (RFC 7469-Form).
  3. Belassen Sie tsa.warn_on_key_rotation auf true, damit eine geänderte SPKI protokolliert wird, bevor das gepinnte Zertifikat abläuft.
  4. Beziehen Sie tsa.url ausschließlich aus vertrauenswürdiger Konfiguration. Wenn ein Betreiber den Wert über eine Adminoberfläche setzen kann, wenden Sie eine Egress-Firewall- oder DNS-Richtlinie an, um die Angriffsfläche für Request Forgery zu verringern.

Verwenden Sie Psr\Log\LoggerInterface für Diagnosen. Übergeben Sie strukturierten Kontext, keine interpolierten Strings. PSR-3 überlässt das Escaping der Platzhalter der Logger-Implementierung und weist Aufrufer an, Kontextwerte nicht vorab zu escapen (PSR-3 §1.2). Protokollieren Sie die Exception-Klasse, nicht die Nachricht oder den Trace, um interne Details in den Logs zu reduzieren.

resource: config/nextpdf.php (tsa hardening) + src/Laravel/NextPdfServiceProvider.php
<?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
],
],
];
  • Der Satz von Antwortheadern ist fest. Anwendungen, die eine andere CSP benötigen, müssen die Antwort nachbearbeiten, nachdem die Factory sie zurückgegeben hat.
  • Die Pfadvalidierung läuft auf dem Worker. Ein fehlerhafter Pfad durchläuft dispatch() und scheitert erst, wenn der Job ausgeführt wird.
  • tsa.allow_insecure_http = true entfernt die HTTPS-Erzwingung und schwächt das Vertrauen in den Zeitstempel. Beschränken Sie dies auf die lokale Entwicklung.
  • Die Fontregistry wird nach dem Warmup gesperrt; ein Laufzeitversuch, in einem langlebigen Worker einen Font zu registrieren, wird per Design abgelehnt.

Die Sicherheitskontrollen sind konstantzeitige String- und Array-Operationen und verursachen keine messbaren Kosten pro Anfrage. Der dominierende Betriebskostenfaktor ist das Font-Parsing bei der ersten Verwendung; laden Sie Fonts beim Worker-Boot vor, um Latenz bei der ersten Anfrage zu vermeiden.

Diese Seite ist die Bedrohungsmodell-Referenz für das Paket. Die hier beschriebenen Kontrollen sind im Quellcode durchgesetzt und durch die Testsuite abgesichert. Die Deployment-Konfiguration, die der Betreiber bereitstellen muss, ist in der Bedrohungsmodell-Tabelle und in den Schritten zur Zeitstempelinstanz hervorgehoben.

AussageQuelleAbschnittreference_id
PSR-18-Client sendet PSR-7-Anfrage, gibt PSR-7-Antwort zurückPSR-18 HTTP Client§2
Aufrufer übergibt nicht vorab escapten strukturierten Log-KontextPSR-3 Logger§1.2

RFC 7469-SPKI-Pinning wird als die Form genannt, die der Konfigurationsschlüssel tsa.pinned_public_keys verwendet; das Paket konsumiert vom Betreiber bereitgestellte Pin-Werte und implementiert den RFC nicht selbst.

PAdES B-B-Signierung und die Integration der Zeitstempelinstanz erfordern nextpdf/premium. Dies ist eine optionale Funktion der Enterprise-Stufe; das hier dokumentierte Core-Paket benötigt keine Code-Änderung, um sie zu übernehmen. Siehe https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/configuration/ – alle TSA-, Signatur- und Queue-Schlüssel
  • /integrations/laravel/production-usage/ – DI- und Fehlerbehandlungsmuster
  • /integrations/laravel/troubleshooting/ – warum die Pfadprüfungen Eingaben ablehnen
  • /integrations/laravel/boot-and-discovery/ – Bindungslebensdauern in langlebigen Workern