Enterprise редакция
Content Disarm and Reconstruction — глубокий справочник
Эта страница — глубокий справочник по модулю NextPDF\Enterprise\Security\Cdr. Модуль обезвреживает недоверенный PDF и восстанавливает чистый файл из его безопасных объектов. Конвейер таков: разбор, контроль приёма, обнаружение угроз, фильтрация, очистка ссылок, пересборка. Выход — это проекция входа с точки зрения безопасности, а не доказательная копия. За рекомендациями по рабочему процессу сначала прочитайте страницу возможностей CDR.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в составе NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без соответствующего права доступа не загружает классы этой возможности. Сравните редакции и получите лицензию.
Публичная поверхность API
Заголовок раздела «Публичная поверхность API»| Символ | Параметры | Поведение по умолчанию | Возвращает | Бросает или завершается ошибкой | Примечания |
|---|---|---|---|---|---|
CdrEngine::__construct | нет | Конструирует внутренние детектор и построитель | CdrEngine | Ничего не объявлено | Нет внедряемых зависимостей |
CdrEngine::sanitize | string $pdfData, ?CdrPolicy $policy = null | Запускает полный конвейер под CdrPolicy::standard() | CdrResult | Не бросает на враждебном входе; сбои разбора и приёма возвращают отклонённый результат | Результат сообщает об отклонении отдельно от обезвреживания |
CdrPolicy::__construct | семь необязательных именованных параметров, см. блок | Пустой набор удаления; allowUriActions false; flattenIncrementalUpdates true; пределы 100000 объектов, 256 МиБ декодированных данных, 10000 страниц, 1000.0 коэффициент раздувания | CdrPolicy | Ничего не объявлено | final readonly; пустой список removeThreatTypes ничего не обнаруживает |
CdrPolicy::standard | нет | Устаревший набор угроз; URI-действия удаляются; пределы по умолчанию | self | Ничего не объявлено | Исключает семь потерь-несущих случаев Strip* |
CdrPolicy::paranoid | нет | Устаревший набор угроз с более жёсткими пределами: 50000 объектов, 128 МиБ, 5000 страниц, 100.0 коэффициент раздувания | self | Ничего не объявлено | Исключает семь потерь-несущих случаев Strip* |
CdrPolicy::permissive | нет | Удаляет только JavaScript, LaunchAction, NamedJavaScript, SubmitForm, ImportData; сохраняет URI-действия | self | Ничего не объявлено | Предназначено для доверенных источников |
CdrPolicy::allThreatTypes | нет | Возвращает каждый случай ThreatType, включая потерь-несущие случаи Strip* | list<ThreatType> | Ничего не объявлено | Явный выбор максимального удаления |
CdrPolicy::legacyThreatTypes | нет | Возвращает каждый случай, кроме семи случаев Strip* | list<ThreatType> | Ничего не объявлено | Набор удаления по умолчанию для standard() и paranoid() |
CdrPolicy::shouldRemove | ThreatType $type | Проверка вхождения в removeThreatTypes | bool | Ничего не объявлено | Возвращает false для UriAction, когда allowUriActions равно true |
ThreatDetector::detect | PdfReader $reader, CdrPolicy $policy | Сканирует каждый объект и каталог трейлера на типы угроз политики | list<DetectedThreat> | Не бросает; неразбираемый объект становится угрозой UnparseableObject | Сканирование каталога охватывает дерево /Names/JavaScript |
CdrRebuilder::rebuild | PdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policy | Сериализует безопасные объекты в файл %PDF-2.0 с единственной ревизией | string | Ничего не объявлено; объекты, у которых не удаётся перечитывание или проверка /Length, пропускаются | $policy зарезервирован для будущих настроек сериализации |
DetectedThreat::__construct | ThreatType $type, int $objectNumber, string $description, string $location = '' | Неизменяемый объект-значение находки | DetectedThreat | Ничего не объявлено | Все четыре свойства — public readonly |
ThreatType | строково-подкреплённый enum | Двадцать случаев: тринадцать устаревших плюс семь опциональных случаев Strip* | н/д | н/д | См. перечень случаев ниже |
Сигнатуры точек входа
Заголовок раздела «Сигнатуры точек входа»final class CdrEngine{ public function __construct()
public function sanitize(string $pdfData, ?CdrPolicy $policy = null): CdrResult}final readonly class CdrPolicy{ public function __construct( public array $removeThreatTypes = [], public bool $allowUriActions = false, public bool $flattenIncrementalUpdates = true, public int $maxObjects = 100_000, public int $maxDecodedStreamBytes = 268_435_456, public int $maxPageCount = 10_000, public float $maxInflationRatio = 1000.0, )
public static function standard(): self
public static function paranoid(): self
public static function permissive(): self
public static function allThreatTypes(): array
public static function legacyThreatTypes(): array
public function shouldRemove(ThreatType $type): bool}final class ThreatDetector{ public function detect(PdfReader $reader, CdrPolicy $policy): array}final class CdrRebuilder{ public function rebuild(PdfReader $reader, array $safeObjNums, array $removedObjNums, CdrPolicy $policy): string}final readonly class DetectedThreat{ public function __construct( public ThreatType $type, public int $objectNumber, public string $description, public string $location = '', )}enum ThreatType: stringПеречень случаев ThreatType
Заголовок раздела «Перечень случаев ThreatType»Тринадцать устаревших случаев образуют набор удаления по умолчанию. Случаи Strip* по замыслу несут потери и никогда не входят в политику по умолчанию.
| Случай | Подкрепляющее значение | Поверхность обнаружения |
|---|---|---|
ThreatType::JavaScript | javascript | Ключ /JS на любом объекте или действие /S /JavaScript |
ThreatType::AdditionalActions | additional-actions | Словарь /AA на любом объекте |
ThreatType::OpenAction | open-action | Ключ /OpenAction на любом объекте |
ThreatType::LaunchAction | launch-action | Действие /S /Launch |
ThreatType::RemoteGoTo | remote-goto | Действие /S /GoToR или /S /GoToE |
ThreatType::SubmitForm | submit-form | Действие /S /SubmitForm |
ThreatType::ImportData | import-data | Действие /S /ImportData |
ThreatType::EmbeddedFiles | embedded-files | Дерево имён /EmbeddedFiles или словарь /EF |
ThreatType::RichMedia | rich-media | /Subtype /RichMedia |
ThreatType::NamedJavaScript | named-javascript | Дерево имён каталога /Names/JavaScript |
ThreatType::UriAction | uri-action | Действие /S /URI; подавляется, когда allowUriActions равно true |
ThreatType::Xfa | xfa | Ключ /XFA |
ThreatType::UnparseableObject | unparseable-object | Любой объект или каталог, разбор которого не удался |
ThreatType::StripJavaScript | strip-javascript | Опциональный надмножество: ключ /JS, /S /JavaScript или /Subtype /JavaScript |
ThreatType::StripEmbeddedFiles | strip-embedded-files | Опционально: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles или /EF |
ThreatType::StripFormFields | strip-form-fields | Опционально: /Subtype /Widget, ключ /FT или ключ /AcroForm |
ThreatType::StripAnnotationsRich | strip-annotations-rich | Опциональные подтипы: Movie, Sound, FileAttachment, 3D, RichMedia, Screen |
ThreatType::StripOcgNonDefault | strip-ocg-non-default | Опционально: /Type /OCG с ключом /Usage или /Visibility |
ThreatType::StripDigitalSignaturesAtRebuild | strip-digital-signatures-at-rebuild | Опционально: /Type /Sig, /FT /Sig, /DSS, /VRI или /ByteRange |
ThreatType::Strip3dAndRichMedia | strip-3d-and-rich-media | Опциональные подтипы: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie |
Контракт поведения
Заголовок раздела «Контракт поведения»CdrEngine::sanitize выполняет шесть упорядоченных фаз и никогда не бросает исключение для враждебного входа.
- Разбор. Сбой разбора возвращает результат с
admittedfalse и причиной отклонения из-за ошибки разбора. Обезвреженный выход в этом случае пуст. - Контроль приёма. Число объектов, совокупный объём декодированных байтов потоков, коэффициент раздувания на поток и число страниц проверяются на соответствие пределам политики. Документ, превышающий пределы, отклоняется, а не обезвреживается. Отклонение и обезвреживание сообщаются отдельно.
- Обнаружение.
ThreatDetector::detectсканирует каждый объект и каталог трейлера на типы угроз политики. Неразбираемые объекты записываются как находкиThreatType::UnparseableObject, а не пропускаются. - Фильтрация. Объекты с находками ставятся в очередь на удаление. Каталог документа никогда не удаляется как целый объект. Находки на уровне каталога (
OpenAction,AdditionalActions,NamedJavaScript) вместо этого устраняются удалением ключей. - Очистка ссылок. Каждая косвенная ссылка на удалённый объект заменяется на
nullпри сериализации. - Пересборка.
CdrRebuilder::rebuildвыдаёт файл%PDF-2.0с единственной ревизией, перенумерованными объектами, классической таблицей перекрёстных ссылок и свежим трейлером. Байты безопасных потоков копируются побайтово идентично. Пересобранный каталог отбрасывает/OpenAction,/AAи/Names;/AAотбрасывается у каждого объекта.
Возвращаемый CdrResult предоставляет пересобранные байты, список удалённых угроз, оба размера в байтах, флаг приёма и причину отклонения. Если у источника был разрешимый /Root, а пересобранный выход его потерял, движок отклоняет выход, вместо того чтобы вернуть структурно повреждённый файл. Это отказоустойчивая гарантия: admitted true означает, что выход по-прежнему несёт ссылку на каталог документа.
Инкрементные обновления никогда не выживают: пересборка сериализует ровно одну ревизию при любой политике, поэтому теневые поздние ревизии сплющиваются самой конструкцией. Исходные цифровые подписи не могут остаться действительными после пересборки, поскольку диапазоны байтов больше не совпадают с выходом.
Архитектурная красная линия. CDR — это слой проекции безопасности, а не слой сохранения. Выход нельзя использовать для юридического сохранения доказательств, сравнения хешей с оригиналом или архивных копий.
Пограничные случаи и режимы отказа
Заголовок раздела «Пограничные случаи и режимы отказа»- Политика
nullразрешается вCdrPolicy::standard(). Политика, сконструированная с пустым по умолчаниюremoveThreatTypes, ничего не обнаруживает и не удаляет. allowUriActions, установленный вtrue, подавляет удалениеUriAction, даже когда этот случай присутствует вremoveThreatTypes.flattenIncrementalUpdatesв этом выпуске декларативен: пересборка выдаёт единственную ревизию при любой политике, включаяpermissive(), которая устанавливает флаг вfalse.- Проверка коэффициента раздувания трактует нулевую сырую длину потока как единицу, поэтому поток, раздувающийся из ничего, всё равно ограничен. Когда декодированная форма не сохраняется, сырая длина потока учитывается в совокупном бюджете.
- Проверка приёма по числу страниц действует по мере возможности: сбой чтения каталога или дерева страниц сам по себе не отклоняет документ. Бюджеты по числу объектов и декомпрессии всегда применяются.
- Объект, у которого сырая длина потока расходится с целочисленной записью
/Length, пропускается при пересборке (защита от полиглотов). Ссылка на такой пропущенный объект сохраняет свой исходный номер объекта и может не разрешиться в выходе.sanitize()отвергает обнаружимо повреждённые результаты (отсутствующий/Root), но вызывающий код, который напрямую управляет низкоуровневымCdrRebuilder::rebuild(), должен сам повторно проверить структуру выхода и целостность ссылок. - Когда исходный трейлер несёт
/ID, пересобранный трейлер несёт заново сгенерированный случайный/ID, а не исходный. Другие записи трейлера, включая/Info, не переносятся; пересобранный трейлер содержит/Size,/Root(когда разрешим) и перегенерированный/ID. - Декодированные байты имён и ключей переиздаются с шестнадцатеричными экранированиями для разделителей, пробельных символов и непечатаемых байтов, поэтому враждебные имена не могут внедрить синтаксис словаря в выход.
- Строковые значения под ключами словаря вне известного набора имя-значащих ключей консервативно выдаются как литеральные строки.
CdrPolicy::legacyThreatTypes()трактует любой будущий случай enum как удаляемый по умолчанию, если он не зарегистрирован как случайStrip*, поэтому новые несущие потери случаи не могут молча войти в политики по умолчанию.- CDR не является криптографическим модулем. Единственное использование случайности в нём — перегенерированный
/IDтрейлера. Проверка подписи здесь вне области рассмотрения; см. глубокий справочник по подписи.
Соответствие
Заголовок раздела «Соответствие»| Утверждение | Стандарт | Пункт |
|---|---|---|
| Вызов действия ECMAScript заставляет процессор PDF выполнить встроенный скрипт. | ISO 32000-2 | §12.6.4.17 |
Скрипты уровня документа в дереве имён JavaScript все выполняются при открытии документа. | ISO 32000-2 | §12.6.4.17 |
Словарь имён каталога может содержать дерево имён JavaScript со скрипт-действиями уровня документа. | ISO 32000-2 | §7.7.4 (Table 32) |
| Действие запуска запускает приложение либо открывает или печатает документ. | ISO 32000-2 | §12.6.4.6 |
Словари дополнительных действий /AA расширяют события-триггеры на аннотациях, страницах, полях и каталоге. | ISO 32000-2 | §12.6.3 |
| Приём недоверенных файлов должен ограничивать наличие, объём и содержимое входящих файлов. | OWASP ASVS 5.0 | §5.2 |
| Системы должны предотвращать ненадлежащее выполнение загруженных файлов и обнаруживать опасное содержимое. | OWASP ASVS 5.0 | §5.3 |
Все пункты пересказаны; NextPDF не воспроизводит нормативный текст. NextPDF не заявляет о сертификации. CDR удаляет поверхности активного содержимого, перечисленные в ThreatType, согласно настроенной политике; это возможность, а не сертифицированный обезвреживатель. CDR не является антивирусным сканером и не обнаруживает сигнатуры вредоносного ПО; он дополняет, но не удовлетворяет такие меры контроля, как антивирусное сканирование OWASP ASVS 5.4.3. Приемлем ли обезвреженный файл для конкретного канала приёма — остаётся решением о риске на стороне оператора.
Заметки по разработке
Заголовок раздела «Заметки по разработке»- Исходный код модуля несёт
@since 1.9.0; этот справочник документирует поверхность в том виде, в каком она поставлена вnextpdf/enterprise3.1.0. - Всё выполняется в рамках процесса на вашем хосте. Во время обезвреживания сетевой доступ не происходит.
CdrPolicyиDetectedThreat—final readonly; чтобы изменить пределы, сконструируйте новый экземпляр политики.CdrEngineконструирует свои детектор и построитель внутренне.ThreatDetectorиCdrRebuilderостаются напрямую пригодными для поэтапных конвейеров, которые поставляют собственныйPdfReader.- Параметр
$policyметодаCdrRebuilder::rebuildсейчас зарезервирован; исходный код документирует его как сохранённый для совместимости мест вызова и будущих настроек сериализации на уровне политики. - Выход структурно воспроизводим, но не побитово: перегенерированный
/IDотличается при каждом запуске, когда источник его нёс. - Тип результата
CdrResult(возвращаемое значениеsanitize()) охвачен поведенчески выше; его поля —public readonly, сhadThreats()иthreatCount()в качестве удобных методов.
См. также
Заголовок раздела «См. также»- Content Disarm and Reconstruction (CDR) — страница возможности с рекомендациями по рабочему процессу и политике.
- Security — глубокий справочник
- Validation — глубокий справочник
- Forensics — глубокий справочник
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов вне области рассмотрения.