Skip to content

Sicherheit Overview

TCPDF-Next is built on a security-first design philosophy. Every component, from cryptographic primitives to HTML parsing, is engineered to eliminate entire categories of vulnerabilities rather than patch them after discovery.

Sicherheit-First Design Philosophy

Sicherheit in TCPDF-Next is not a feature bolted on top of a legacy codebase. It is an architectural constraint that influenced every design decision from day one:

  • Deny by default — External resource loading, network requests, and file access are blocked unless explicitly allowed.
  • Fail closed — When a security check cannot be performed (e.g., OCSP responder unreachable), the operation fails rather than proceeding insecurely.
  • Defense in depth — Multiple independent layers of protection ensure that a single bypass does not compromise the system.
  • Minimal attack surface — Zero runtime Composer dependencies. All cryptographic operations use PHP's built-in OpenSSL and Sodium extensions.

AES-256 Encryption (No Legacy Algorithms)

TCPDF-Next exclusively implements AES-256 encryption as defined in PDF 2.0 (ISO 32000-2, Revision 6). All legacy and insecure algorithms are permanently rejected:

AlgorithmStatusReason
AES-256-CBCSupportedPDF 2.0 standard, no known practical attacks
RC4 (40-bit / 128-bit)ProhibitedStream cipher with known biases and practical attacks
AES-128ProhibitedInsufficient margin for long-term confidentiality
DES / 3DESNot implementedBlock size and key length vulnerabilities
MD5 (for key derivation)ProhibitedCollision attacks since 2004
php
use YeeeFang\TcpdfNext\Encryption\EncryptionAlgorithm;
use YeeeFang\TcpdfNext\Encryption\Permissions;

$pdf->setEncryption()
    ->setAlgorithm(EncryptionAlgorithm::AES256)
    ->setUserPassword('reader-password')
    ->setOwnerPassword('admin-password')
    ->setPermissions(
        Permissions::PRINT_HIGH_QUALITY
        | Permissions::COPY
        | Permissions::ACCESSIBILITY
    )
    ->apply();

PAdES Digital Signatures (B-B through B-LTA)

TCPDF-Next implements the full PAdES Baseline Profile (ETSI EN 319 142-1) for digital signatures with increasing levels of long-term validity:

LevelBeschreibungValidation Period
PAdES B-BBasic CMS signature with signing certificateCertificate validity (~1-3 years)
PAdES B-T+ RFC 3161 timestamp from a trusted TSATSA certificate validity (~10-15 years)
PAdES B-LT+ Document Sicherheit Store with OCSP/CRL dataAlgorithm security lifetime (~15-30 years)
PAdES B-LTA+ Archive timestamp for indefinite re-validationIndefinite (with periodic re-timestamping)

For implementation details, see PAdES B-LTA Signatures.

SSRF Protection with DNS Pinning

All external network requests (image fetching, TSA communication, OCSP lookups) pass through a hardened HTTP client with built-in SSRF protection:

  • DNS pinning — Resolved IP addresses are validated before connection. Private network ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), loopback (127.0.0.0/8), and link-local (169.254.0.0/16) addresses are blocked.
  • Protocol restriction — Only https:// is permitted by default. Plain http:// is rejected unless explicitly allowed.
  • Domain allowlisting — Configurable allowlist for permitted external domains.
  • Redirect following — Limited to a configurable maximum (default: 3) with re-validation at each hop.

Path Traversal Prevention

All file path operations are sanitized to prevent directory traversal attacks:

  • Embedded file names are stripped of path separators and .. sequences.
  • Font file paths are resolved to absolute canonical paths and validated against allowed directories.
  • Image paths referenced in HTML are restricted to explicitly configured directories via ResourcePolicy.

#[\SensitiveParameter] on Passwords and Keys

All method parameters that accept passwords, passphrases, private keys, or PINs are annotated with PHP 8.2's #[\SensitiveParameter] attribute. This ensures that sensitive values are automatically redacted from stack traces, error logs, and exception messages:

php
public function setUserPassword(
    #[\SensitiveParameter] string $password
): self { /* ... */ }

public function setCertificate(
    string $certificate,
    #[\SensitiveParameter] string $privateKey,
    #[\SensitiveParameter] string $passphrase = ''
): self { /* ... */ }

#[\NoDiscard] on Critical Return Values

Methods that return security-critical results (validation outcomes, signature verification) are annotated with #[\NoDiscard] to prevent callers from ignoring return values:

php
#[\NoDiscard]
public function validate(string $pdfPath): ValidationResult { /* ... */ }

#[\NoDiscard]
public function verify(): SignatureVerificationResult { /* ... */ }

Ignoring these return values produces a compiler warning, catching a common class of security bugs at development time.

PHPStan Level 10 (Zero Errors, No Baseline)

The entire codebase passes PHPStan static analysis at the strictest level (Level 10) with zero errors and no baseline file. This means:

  • No @phpstan-ignore annotations anywhere in the codebase.
  • No suppressed error categories.
  • All types are fully specified, including generics and template types.
  • All dead code paths are eliminated.

100% declare(strict_types=1)

Every PHP file in TCPDF-Next begins with declare(strict_types=1). There are no exceptions. This eliminates an entire class of type coercion bugs that have historically led to security vulnerabilities in PHP applications.

OWASP Compliance Considerations

TCPDF-Next addresses the following OWASP categories relevant to PDF generation libraries:

OWASP CategoryMitigation
A01 — Broken Access ControlGranular PDF permissions, certificate-based encryption
A02 — Cryptographic FailuresAES-256 only, no weak algorithms, constant-time comparisons
A03 — InjectionHTML sanitization, path traversal prevention, no eval()
A05 — Sicherheit MisconfigurationSecure defaults, deny-by-default resource policies
A06 — Vulnerable ComponentsZero runtime dependencies, built-in crypto via OpenSSL/Sodium
A07 — Authentication Failures#[\SensitiveParameter], secure memory wiping via sodium_memzero()
A10 — SSRFDNS pinning, private network blocking, domain allowlisting

Sicherheit Documentation

Explore the full security documentation:

Veröffentlicht unter der LGPL-3.0-or-later Lizenz.