Перейти к содержимому

Безопасность и эксплуатация пакета NextPDF для Laravel

Пакет задаёт фиксированные заголовки HTTP-ответа для формата Portable Document Format (PDF), очищает имена скачиваемых файлов, проверяет на воркере выходные пути заданий очереди и направляет вызовы по протоколу передачи гипертекста (HTTP) к службе меток времени через клиент с защитой от подделки запросов. На этой странице описаны модель угроз и конфигурация развёртывания, необходимые для каждого из этих механизмов.

Окно терминала
composer require nextpdf/laravel
php artisan vendor:publish --tag=nextpdf-config

Пакет подключает движок PDF к веб-фреймворку. Границу доверия определяют HTTP-запрос и транспорт очереди. Эти механизмы охватывают обработку ответов, десериализованные полезные нагрузки заданий и исходящий HTTP к службе меток времени.

АктивУгрозаМеханизм в этом пакетеТребуемая конфигурация развёртывания
HTTP-ответ с PDFПодбор типа содержимого, кликджекинг, индексированиеФиксированный набор заголовков, который задаёт каждая PdfResponse-фабрикаНет; заголовки не настраиваются
Имя скачиваемого файлаВнедрение заголовка, обход каталога в Content-DispositionОчиститель имени файла удаляет разделители, управляющие символы и нулевые байтыНет; очиститель выполняется всегда
Выходной путь задания очередиПроизвольная запись в файл через подменённую сериализованную полезную нагрузкуПуть проверяется в handle() на воркереНаправляйте вывод в контролируемый путь хранилища
Исходящий HTTP к службе меток времени (TSA)Подделка запроса на стороне сервера, подмена открытого текстаHTTP-клиент с защитой от подделки запросов; HTTPS используется принудительно, если это явно не ослабленоОставьте tsa.allow_insecure_http = false; закрепите Subject Public Key Info (SPKI)
Общее состояние воркераУтечка состояния между запросами в долгоживущих воркерахЗаблокированный реестр шрифтов; ограниченный кэш изображений; документ, привязанный к фабрикеЗадайте preload_fonts; ограничьте память на уровне контейнера

Каждая фабрика PdfResponse задаёт фиксированный набор заголовков:

  • 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

Эти значения — константы в PdfResponse. Они не настраиваются. Набор тестов пакета проверяет каждый заголовок для каждого метода-фабрики, включая потоковые варианты.

Имя скачиваемого файла проходит через очиститель, прежде чем попасть в заголовок Content-Disposition. Очиститель удаляет разделители пути, управляющие символы и нулевые байты, а для имён вне ASCII формирует параметр filename*= по стандарту Request for Comments (RFC) 5987. Пустое имя файла заменяется на document.pdf.

GeneratePdfJob сериализует замыкание в транспорт очереди. Воркер проверяет выходной путь внутри handle(), а не при диспетчеризации. Проверка отклоняет:

  • нулевые байты в пути,
  • схемы потоковых обёрток (например php://),
  • .. — сегменты обхода каталога,
  • любой путь, который не заканчивается на .pdf (без учёта регистра).

Каждое отклонение вызывает InvalidArgumentException. Проверка выполняется, когда воркер обрабатывает задание. Сериализованную полезную нагрузку в транспорте Redis или базы данных можно изменить до того, как воркер её прочитает. Направляйте выходной путь в контролируемый каталог хранилища; не формируйте его из непроверенных данных запроса.

Когда настроена служба меток времени, пакет привязывает Psr\Http\Client\ClientInterface по стандарту PHP Standard Recommendation (PSR)-18. Клиент PSR-18 отправляет запрос PSR-7 и возвращает ответ PSR-7 (PSR-18 §2). Привязанный клиент оборачивает клиент на основе curl слоем с защитой от подделки запросов. Он принудительно использует HTTPS, если только tsa.allow_insecure_http явно не равно true.

Служба меток времени — возможность уровня Premium. Описанный здесь пакет Core привязывает HTTP-клиент и обвязку клиента меток времени; для самого подписания требуется nextpdf/premium. На этой странице не описывается поведение базового профиля PDF Advanced Electronic Signatures (PAdES) выше B-B; более высокие профили выходят за рамки.

Рекомендации по эксплуатации службы меток времени:

  1. Оставляйте tsa.allow_insecure_http равным false в промышленной среде.
  2. Задайте tsa.pinned_public_keys равным хешам SPKI SHA-256 в base64 для сертификата службы меток времени (форма RFC 7469).
  3. Оставляйте tsa.warn_on_key_rotation равным true, чтобы изменение SPKI было записано в журнал до истечения срока действия закреплённого сертификата.
  4. Берите tsa.url только из доверенной конфигурации. Если оператор может задать его через административный интерфейс, примените egress-файрвол или политику DNS, чтобы снизить риск подделки запросов.

Используйте Psr\Log\LoggerInterface для диагностики. Передавайте структурированный контекст, а не интерполированные строки. PSR-3 оставляет экранирование плейсхолдеров на усмотрение реализации журнала и предписывает вызывающей стороне не экранировать значения контекста заранее (PSR-3 §1.2). Записывайте класс исключения, а не сообщение или трассировку, чтобы сократить объём внутренних подробностей в журналах.

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
],
],
];
  • Набор заголовков ответа фиксирован. Приложениям, которым нужна другая политика безопасности содержимого (CSP), нужно постобрабатывать ответ после того, как фабрика его вернёт.
  • Проверка пути выполняется на воркере. Неправильный путь проходит dispatch() и завершается ошибкой только при выполнении задания.
  • tsa.allow_insecure_http = true снимает принудительное использование HTTPS и ослабляет доверие к меткам времени. Ограничьте его локальной разработкой.
  • Реестр шрифтов блокируется после прогрева; пакет по замыслу отклоняет попытки зарегистрировать шрифт во время выполнения в долгоживущем воркере.

Механизмы безопасности используют операции со строками и массивами с постоянным временем выполнения и не добавляют измеримых затрат на запрос. Разбор шрифтов при первом использовании — основная эксплуатационная затрата; предзагружайте шрифты при старте воркера, чтобы избежать задержки на первом запросе.

Эта страница — справочник по модели угроз для пакета. Исходный код обеспечивает соблюдение этих механизмов, а набор тестов подтверждает это. Таблица модели угроз и шаги по службе меток времени указывают конфигурацию развёртывания, которую должен предоставить оператор.

УтверждениеИсточникПунктидентификатор ссылки (reference_id)
Клиент PSR-18 отправляет запрос PSR-7, возвращает ответ PSR-7PSR-18 HTTP Client (клиент HTTP)§2
Вызывающая сторона передаёт неэкранированный структурированный контекст журналаPSR-3 Logger (логгер)§1.2

Закрепление SPKI по RFC 7469 задаёт форму, используемую ключом конфигурации tsa.pinned_public_keys. Пакет потребляет значения закрепления, предоставленные оператором, и сам не реализует данный RFC.

Для подписания PAdES B-B и интеграции со службой меток времени требуется nextpdf/premium. Эта необязательная возможность уровня Enterprise не требует изменений в коде описанного здесь пакета Core. См. https://nextpdf.dev/get-license/?intent=laravel-signing.

  • /integrations/laravel/configuration/ — каждый ключ TSA, подписи и очереди
  • /integrations/laravel/production-usage/ — внедрение зависимостей (DI) и шаблоны обработки ошибок
  • /integrations/laravel/troubleshooting/ — почему проверки пути отклоняют ввод
  • /integrations/laravel/boot-and-discovery/ — времена жизни привязок в долгоживущих воркерах