NextPDF Symfony: безопасность и эксплуатация
Помощники формирования ответа применяют фиксированный набор заголовков безопасности. Объект передачи данных (DTO) асинхронного сообщения дважды проверяет выходной путь. Цифровая подпись необязательна и в редакции Pro ограничена базовым профилем, описанным здесь.
HTTP-заголовки безопасности в ответе
Заголовок раздела «HTTP-заголовки безопасности в ответе»NextPDF\Symfony\Http\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 |
Для создаваемых документов эти заголовки снижают риск content-type sniffing, отображения во фреймах, индексации и утечки реферера. Буферизованные варианты также задают Content-Type: application/pdf и Content-Length. Потоковые варианты задают тип содержимого и намеренно не задают Content-Length.
Бандл фиксирует этот набор заголовков. Чтобы добавить или изменить заголовки, например задать более строгий Cache-Control для скачиваний с аутентификацией, измените возвращаемый объект Response в контроллере перед его возвратом.
Content-Disposition и обработка имени файла
Заголовок раздела «Content-Disposition и обработка имени файла»PdfResponse формирует заголовок Content-Disposition с защитными мерами. PdfResponseTest проверяет это поведение:
- Имя файла очищается: разделители пути и последовательности обхода каталогов удаляются, поэтому имя вида
../../../etc/passwd.pdfне может выйти за пределы каталога. - Расширение
.pdfдобавляется, если его нет; существующее расширение не дублируется, в том числе в верхнем регистре.PDF. - Двойные кавычки и обратные слеши экранируются в строковой форме с кавычками.
- Имена файлов вне ASCII получают запасной вариант в ASCII и вариант
filename*=UTF-8''по RFC-5987 (Request for Comments 5987). - Пустое имя файла заменяется на
document.pdf.
Если имя файла зависит от пользовательского ввода, передавайте его только после проверки авторизации на уровне приложения. Бандл выполняет очистку для безопасности заголовка, а не для контроля доступа.
Асинхронная проверка выходного пути
Заголовок раздела «Асинхронная проверка выходного пути»NextPDF\Symfony\Message\GeneratePdfMessage проверяет выходной путь в своём конструкторе. NextPDF\Symfony\Message\GeneratePdfHandler повторно проверяет его во время выполнения перед записью. При создании отклоняются:
- пустой путь или путь, содержащий нулевой байт;
- схема stream-wrapper, например
php://...; - сегмент обхода каталогов
..с разделителем/или\; - путь, не оканчивающийся на
.pdf(без учёта регистра); - значение
builderClass, не являющееся синтаксически корректным именем класса.
Вторая проверка в обработчике важна, поскольку сообщение может оставаться в очереди между отправкой и обработкой. Обработчик не доверяет пути из очереди и снова применяет проверку пути перед сохранением. Запускайте обработчики от имени учётной записи файловой системы с минимальными привилегиями и доступом, ограниченным целевым выходным каталогом.
Граница разрешения построителя
Заголовок раздела «Граница разрешения построителя»GeneratePdfHandler разрешает построители через сервис-локатор PHP Standard Recommendation 11 (PSR-11) по ключу — имени класса — и отклоняет всё, что не реализует PdfBuilderInterface. Поскольку локатор предоставляет только зарегистрированные построители, контролируемое злоумышленником значение builderClass в подделанной полезной нагрузке транспорта не может создать экземпляр произвольного класса. Согласно PSR-11, если контейнер сообщает, что идентификатор отсутствует, попытка разрешить его завершается ошибкой, а не молча возвращает неожиданный объект (PSR-11 §1.1.2). Регистрируйте в локаторе только доверенные классы построителей.
Необязательная конфигурация цифровой подписи
Заголовок раздела «Необязательная конфигурация цифровой подписи»Цифровая подпись не входит в основной бандл. Она активируется только при наличии nextpdf/premium (который устанавливает редакцию Pro), когда compiler pass обнаруживает классы подписи из Pro. Когда бандл и редакция Pro установлены, поддерживаемая и документированная конфигурация подписи — профиль базового уровня B-B.
Узел конфигурации signature.level принимает дополнительные строковые значения для совместимости схемы в рамках семейства конфигураций NextPDF. В этом бандле поставляется и поддерживается возможность подписи B-B. Документация NextPDF Premium описывает профили подписи помимо B-B, их требования и аспекты эксплуатации. Здесь они намеренно не описываются.
Эксплуатационные замечания для сценария подписи B-B:
- Подписант регистрируется только тогда, когда
signature.enabledимеет значение true и заданsignature.certificate; в противном случае раздел неактивен. - Передавайте сертификат, закрытый ключ и пароль через секреты Symfony или переменные окружения. Никогда не добавляйте их в репозиторий.
- Ограничьте права на чтение ключевого материала только учётной записью приложения.
Необязательное журналирование
Заголовок раздела «Необязательное журналирование»Реестры шрифтов и изображений принимают необязательный Psr\Log\LoggerInterface, привязанный через nullOnInvalid(). При наличии он выступает как заменяемая зависимость в рамках контракта логгера PHP Standard Recommendation 3 (PSR-3) (PSR-3). Удаляйте данные, идентифицирующие пользователя, из любого контекста журнала, который вы добавляете при создании документов; бандл не записывает в журнал содержимое документов.
Контрольный список усиления защиты при эксплуатации
Заголовок раздела «Контрольный список усиления защиты при эксплуатации»- Сохраняйте фиксированные заголовки ответа; для скачиваний с аутентификацией добавляйте более строгое кэширование на уровне контроллера.
- Авторизуйте запрос перед созданием или возвратом документа; бандл не выполняет контроль доступа.
- Храните ключевой материал для подписи в секретах Symfony / переменных окружения с правами доступа к файлам по принципу минимальных привилегий.
- Запускайте обработчики Messenger под учётной записью с минимальными привилегиями и правом записи только в выходной каталог.
- Держите
ext-mbstringиext-zlibвключёнными (иначе бандл сразу завершается с ошибкой). - Зафиксируйте в приложении одну мажорную версию
nextpdf/core, чтобы версия движка была детерминированной между развёртываниями.
Соответствие
Заголовок раздела «Соответствие»Каждая строка содержит нормативное утверждение с этой страницы и привязана к полному 64-символьному шестнадцатеричному reference_id из закрытого корпуса организации по разработке стандартов (SDO). Происхождение (манифест корпуса, транспорт извлечения) указано в _sidecars/rag-citations.yaml.
| Спецификация | Раздел | идентификатор (reference_id) | Утверждение |
|---|---|---|---|
| PSR-11 | psr_11_container#1.1.2.p5 | если has() возвращает false, то get() выбрасывает NotFoundException | |
| PSR-3 | psr_3_logger#x3.p17 | Необязательный компонент логгера |
Коммерческий контекст
Заголовок раздела «Коммерческий контекст»Цифровая подпись доступна только при установленном nextpdf/premium (Pro); поставляемый профиль этого бандла — базовый B-B. Эта необязательная возможность Pro не требует изменений кода в описанном здесь бандле Core. См. </get-license/?intent=symfony-pro>.
См. также
Заголовок раздела «См. также»- /integrations/symfony/production-usage/ — безопасность обработчиков и потоковая передача.
- /integrations/symfony/configuration/ — таблицы signature, tsa и service.
- /integrations/symfony/troubleshooting/ — диагностика проблем с подписью и Messenger.
- /integrations/symfony/integration/ — полный справочник по сквозной настройке.