Skip to content

NextPDF Symfony security and operations

The response helpers apply a fixed set of security headers. The async message data transfer object (DTO) validates its output path twice. Signing is optional and, with the Pro tier, limited to the baseline profile documented here.

NextPDF\Symfony\Http\PdfResponse applies the same header set to every response it builds: inline, download, and both streamed variants. The source constant verifies these exact headers:

HeaderValue
Cache-Controlprivate, max-age=0, must-revalidate
Pragmapublic
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Content-Security-Policydefault-src 'none'
X-Robots-Tagnoindex, nofollow
Referrer-Policyno-referrer

These headers reduce content-type sniffing, framing, indexing, and referrer leakage for generated documents. The buffered variants also set Content-Type: application/pdf and Content-Length. The streamed variants set the content type and omit Content-Length by design.

The bundle fixes this header set. To add or change headers, such as a stricter Cache-Control for authenticated downloads, mutate the returned Response in your controller before returning it.

PdfResponse builds the Content-Disposition header defensively. PdfResponseTest verifies this behavior:

  • The filename is sanitized; path separators and traversal sequences are stripped, so a filename such as ../../../etc/passwd.pdf cannot escape.
  • A .pdf extension is appended when absent; an existing extension is not duplicated, including an uppercase .PDF.
  • Double quotes and backslashes are escaped for the quoted-string form.
  • Non-ASCII filenames receive an ASCII fallback and an RFC-5987 (Request for Comments 5987) filename*=UTF-8'' variant.
  • An empty filename falls back to document.pdf.

Pass a user-influenced filename only after your application-level authorization check. The bundle sanitizes for header safety, not for access control.

NextPDF\Symfony\Message\GeneratePdfMessage validates the output path in its constructor. NextPDF\Symfony\Message\GeneratePdfHandler re-validates it at execution time before writing. Construction rejects:

  • empty path, or a path containing a null byte;
  • a stream-wrapper scheme such as php://...;
  • a .. traversal segment using either / or \ separators;
  • a path not ending in .pdf (case-insensitive);
  • a builderClass that is not a syntactically valid class name.

The second validation in the handler matters because a message can persist in a queue between dispatch and consumption. The handler does not trust the queued path and applies the path guard again before saving. Run workers under a least-privilege filesystem account scoped to the intended output directory.

GeneratePdfHandler resolves builders from a PHP Standard Recommendation 11 (PSR-11) service locator keyed by class name and rejects anything that is not a PdfBuilderInterface. Because the locator exposes only registered builders, an attacker-controlled builderClass on a tampered transport payload cannot instantiate an arbitrary class. Under PSR-11, when a container reports an id as absent, resolving it fails rather than silently returning something unexpected (PSR-11 §1.1.2). Register only trusted builder classes in the locator.

Digital signing is not part of the core bundle. It activates only when nextpdf/premium (which installs the Pro tier) is present and the compiler pass detects the Pro signing classes. With the bundle and the Pro tier installed, the supported, documented signing configuration is the baseline B-B profile.

The signature.level configuration node accepts additional string values for schema compatibility across the NextPDF configuration family. This bundle’s delivered and supported signing capability is B-B. The NextPDF Premium documentation covers signing profiles beyond B-B, their requirements, and their operational considerations. They are intentionally not described here.

Operational notes for the B-B signing path:

  • The signer is registered only when signature.enabled is true and signature.certificate is set; otherwise the section is inert.
  • Provide the certificate, private key, and password through Symfony secrets or environment variables. Never commit them to the repository.
  • Restrict read permissions on key material to the application account.

The font and image registries accept an optional Psr\Log\LoggerInterface bound with nullOnInvalid(). When present, it is a swappable collaborator under the PHP Standard Recommendation 3 (PSR-3) logger contract (PSR-3). Scrub user-identifying data from any log context you add around document generation; the bundle does not log document content.

  • Keep the fixed response headers; layer stricter caching for authenticated downloads at the controller.
  • Authorize the request before generating or returning a document; the bundle does not perform access control.
  • Store signing key material in Symfony secrets / environment variables with least-privilege file permissions.
  • Run Messenger workers under a least-privilege account with write access limited to the output directory.
  • Keep ext-mbstring and ext-zlib enabled (the bundle fails fast otherwise).
  • Pin a single nextpdf/core major in the application to make the engine version deterministic across deploys.

Each row is a normative claim made on this page, pinned to a full 64-hex reference_id from the gated standards development organization (SDO) corpus. Provenance (corpus manifest, retrieval transport) is in _sidecars/rag-citations.yaml.

SpecClausereference_idClaim
PSR-11psr_11_container#1.1.2.p5has() false implies get() throws NotFoundException
PSR-3psr_3_logger#x3.p17Optional logger collaborator

Digital signing is available only when nextpdf/premium (Pro) is installed; this bundle’s delivered profile is baseline B-B. This optional Pro capability needs no code change in the Core bundle documented here. See </get-license/?intent=symfony-pro>.

  • /integrations/symfony/production-usage/ — worker safety and streaming.
  • /integrations/symfony/configuration/ — the signature, tsa, and service tables.
  • /integrations/symfony/troubleshooting/ — diagnosing signing and Messenger issues.
  • /integrations/symfony/integration/ — end-to-end wiring reference.