Обзор безопасности
TCPDF-Next построен на философии безопасности на первом месте. Каждый компонент, от криптографических примитивов до парсинга HTML, спроектирован для устранения целых категорий уязвимостей, а не для их исправления после обнаружения.
Философия безопасности на первом месте
Безопасность в TCPDF-Next — это не функция, прикрученная поверх устаревшей кодовой базы. Это архитектурное ограничение, повлиявшее на каждое проектное решение с первого дня:
- Запрет по умолчанию — Загрузка внешних ресурсов, сетевые запросы и доступ к файлам заблокированы, если не разрешены явно.
- Отказ при невозможности проверки — Когда проверка безопасности не может быть выполнена (например, OCSP-респондер недоступен), операция завершается ошибкой, а не продолжается небезопасно.
- Глубокая защита — Несколько независимых уровней защиты гарантируют, что обход одного уровня не компрометирует всю систему.
- Минимальная поверхность атаки — Ноль зависимостей Composer времени выполнения. Все криптографические операции используют встроенные расширения PHP OpenSSL и Sodium.
Шифрование AES-256 (без устаревших алгоритмов)
TCPDF-Next реализует исключительно шифрование AES-256, определённое в PDF 2.0 (ISO 32000-2, Revision 6). Все устаревшие и небезопасные алгоритмы навсегда отклоняются:
| Алгоритм | Статус | Причина |
|---|---|---|
| AES-256-CBC | Поддерживается | Стандарт PDF 2.0, без известных практических атак |
| RC4 (40-bit / 128-bit) | Запрещён | Потоковый шифр с известными смещениями и практическими атаками |
| AES-128 | Запрещён | Недостаточный запас для долгосрочной конфиденциальности |
| DES / 3DES | Не реализован | Уязвимости размера блока и длины ключа |
| MD5 (для деривации ключа) | Запрещён | Атаки коллизий с 2004 года |
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 (B-B до B-LTA)
TCPDF-Next реализует полный базовый профиль PAdES (ETSI EN 319 142-1) для цифровых подписей с возрастающими уровнями долгосрочной действительности:
| Уровень | Описание | Период валидации |
|---|---|---|
| PAdES B-B | Базовая CMS-подпись с сертификатом подписанта | Срок действия сертификата (~1-3 года) |
| PAdES B-T | + Метка времени RFC 3161 от доверенного TSA | Срок действия сертификата TSA (~10-15 лет) |
| PAdES B-LT | + Document Security Store с данными OCSP/CRL | Время жизни безопасности алгоритма (~15-30 лет) |
| PAdES B-LTA | + Архивная метка времени для неограниченной повторной валидации | Неограниченный (с периодическим повторным проставлением меток времени) |
Детали реализации смотрите в разделе Подписи PAdES B-LTA.
Защита от SSRF с DNS Pinning
Все внешние сетевые запросы (загрузка изображений, связь с TSA, OCSP-запросы) проходят через защищённый HTTP-клиент со встроенной защитой от SSRF:
- DNS pinning — Разрешённые IP-адреса проверяются перед подключением. Диапазоны частных сетей (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16), loopback (127.0.0.0/8) и link-local (169.254.0.0/16) адреса блокируются. - Ограничение протоколов — По умолчанию разрешён только
https://. Простойhttp://отклоняется, если не разрешён явно. - Белый список доменов — Настраиваемый allowlist разрешённых внешних доменов.
- Следование перенаправлениям — Ограничено настраиваемым максимумом (по умолчанию: 3) с повторной валидацией на каждом переходе.
Защита от обхода путей
Все операции с путями к файлам санитизируются для предотвращения атак обхода каталогов:
- Имена встроенных файлов очищаются от разделителей пути и последовательностей
... - Пути к файлам шрифтов преобразуются в абсолютные канонические пути и проверяются относительно разрешённых каталогов.
- Пути к изображениям, указанным в HTML, ограничиваются явно настроенными каталогами через
ResourcePolicy.
#[\SensitiveParameter] для паролей и ключей
Все параметры методов, принимающие пароли, парольные фразы, приватные ключи или PIN-коды, аннотированы атрибутом #[\SensitiveParameter] PHP 8.2. Это гарантирует автоматическое редактирование конфиденциальных значений из стек-трейсов, логов ошибок и сообщений исключений:
public function setUserPassword(
#[\SensitiveParameter] string $password
): self { /* ... */ }
public function setCertificate(
string $certificate,
#[\SensitiveParameter] string $privateKey,
#[\SensitiveParameter] string $passphrase = ''
): self { /* ... */ }#[\NoDiscard] для критических возвращаемых значений
Методы, возвращающие критически важные с точки зрения безопасности результаты (результаты валидации, верификации подписей), аннотированы #[\NoDiscard] для предотвращения игнорирования возвращаемых значений:
#[\NoDiscard]
public function validate(string $pdfPath): ValidationResult { /* ... */ }
#[\NoDiscard]
public function verify(): SignatureVerificationResult { /* ... */ }Игнорирование этих возвращаемых значений вызывает предупреждение компилятора, выявляя распространённый класс ошибок безопасности на этапе разработки.
PHPStan Level 10 (ноль ошибок, без baseline)
Вся кодовая база проходит статический анализ PHPStan на строжайшем уровне (Level 10) с нулём ошибок и без baseline-файла. Это означает:
- Никаких аннотаций
@phpstan-ignoreнигде в кодовой базе. - Никаких подавленных категорий ошибок.
- Все типы полностью специфицированы, включая generics и template types.
- Все мёртвые пути кода устранены.
100% declare(strict_types=1)
Каждый PHP-файл в TCPDF-Next начинается с declare(strict_types=1). Без исключений. Это устраняет целый класс ошибок приведения типов, которые исторически приводили к уязвимостям безопасности в PHP-приложениях.
Соответствие рекомендациям OWASP
TCPDF-Next решает следующие категории OWASP, актуальные для библиотек генерации PDF:
| Категория OWASP | Защита |
|---|---|
| A01 — Нарушение контроля доступа | Гранулярные разрешения PDF, шифрование на основе сертификатов |
| A02 — Криптографические сбои | Только AES-256, без слабых алгоритмов, сравнение в константном времени |
| A03 — Инъекция | Санитизация HTML, предотвращение обхода путей, без eval() |
| A05 — Неверная конфигурация безопасности | Безопасные настройки по умолчанию, политики ресурсов «запрет по умолчанию» |
| A06 — Уязвимые компоненты | Ноль зависимостей времени выполнения, встроенная криптография через OpenSSL/Sodium |
| A07 — Сбои аутентификации | #[\SensitiveParameter], безопасная очистка памяти через sodium_memzero() |
| A10 — SSRF | DNS pinning, блокировка частных сетей, белый список доменов |
Документация по безопасности
Ознакомьтесь с полной документацией по безопасности:
- Лучшие практики безопасности — Валидация ввода, управление сертификатами, безопасность развёртывания
- Обзор безопасности — Векторы атак на PDF-подписи и их предотвращение