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

Enterprise редакция

Content Disarm and Reconstruction — глубокий справочник

Эта страница — глубокий справочник по модулю NextPDF\Enterprise\Security\Cdr. Модуль обезвреживает недоверенный PDF и восстанавливает чистый файл из его безопасных объектов. Конвейер таков: разбор, контроль приёма, обнаружение угроз, фильтрация, очистка ссылок, пересборка. Выход — это проекция входа с точки зрения безопасности, а не доказательная копия. За рекомендациями по рабочему процессу сначала прочитайте страницу возможностей CDR.

Эта возможность поставляется в составе NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без соответствующего права доступа не загружает классы этой возможности. Сравните редакции и получите лицензию.

СимволПараметрыПоведение по умолчаниюВозвращаетБросает или завершается ошибкойПримечания
CdrEngine::__constructнетКонструирует внутренние детектор и построительCdrEngineНичего не объявленоНет внедряемых зависимостей
CdrEngine::sanitizestring $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::shouldRemoveThreatType $typeПроверка вхождения в removeThreatTypesboolНичего не объявленоВозвращает false для UriAction, когда allowUriActions равно true
ThreatDetector::detectPdfReader $reader, CdrPolicy $policyСканирует каждый объект и каталог трейлера на типы угроз политикиlist<DetectedThreat>Не бросает; неразбираемый объект становится угрозой UnparseableObjectСканирование каталога охватывает дерево /Names/JavaScript
CdrRebuilder::rebuildPdfReader $reader, list<int> $safeObjNums, list<int> $removedObjNums, CdrPolicy $policyСериализует безопасные объекты в файл %PDF-2.0 с единственной ревизиейstringНичего не объявлено; объекты, у которых не удаётся перечитывание или проверка /Length, пропускаются$policy зарезервирован для будущих настроек сериализации
DetectedThreat::__constructThreatType $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

Тринадцать устаревших случаев образуют набор удаления по умолчанию. Случаи Strip* по замыслу несут потери и никогда не входят в политику по умолчанию.

СлучайПодкрепляющее значениеПоверхность обнаружения
ThreatType::JavaScriptjavascriptКлюч /JS на любом объекте или действие /S /JavaScript
ThreatType::AdditionalActionsadditional-actionsСловарь /AA на любом объекте
ThreatType::OpenActionopen-actionКлюч /OpenAction на любом объекте
ThreatType::LaunchActionlaunch-actionДействие /S /Launch
ThreatType::RemoteGoToremote-gotoДействие /S /GoToR или /S /GoToE
ThreatType::SubmitFormsubmit-formДействие /S /SubmitForm
ThreatType::ImportDataimport-dataДействие /S /ImportData
ThreatType::EmbeddedFilesembedded-filesДерево имён /EmbeddedFiles или словарь /EF
ThreatType::RichMediarich-media/Subtype /RichMedia
ThreatType::NamedJavaScriptnamed-javascriptДерево имён каталога /Names/JavaScript
ThreatType::UriActionuri-actionДействие /S /URI; подавляется, когда allowUriActions равно true
ThreatType::XfaxfaКлюч /XFA
ThreatType::UnparseableObjectunparseable-objectЛюбой объект или каталог, разбор которого не удался
ThreatType::StripJavaScriptstrip-javascriptОпциональный надмножество: ключ /JS, /S /JavaScript или /Subtype /JavaScript
ThreatType::StripEmbeddedFilesstrip-embedded-filesОпционально: /Type /EmbeddedFile, /Type /Filespec, /EmbeddedFiles или /EF
ThreatType::StripFormFieldsstrip-form-fieldsОпционально: /Subtype /Widget, ключ /FT или ключ /AcroForm
ThreatType::StripAnnotationsRichstrip-annotations-richОпциональные подтипы: Movie, Sound, FileAttachment, 3D, RichMedia, Screen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultОпционально: /Type /OCG с ключом /Usage или /Visibility
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildОпционально: /Type /Sig, /FT /Sig, /DSS, /VRI или /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaОпциональные подтипы: 3D, U3D, PRC, RMF, RichMedia, Sound, Movie

CdrEngine::sanitize выполняет шесть упорядоченных фаз и никогда не бросает исключение для враждебного входа.

  1. Разбор. Сбой разбора возвращает результат с admitted false и причиной отклонения из-за ошибки разбора. Обезвреженный выход в этом случае пуст.
  2. Контроль приёма. Число объектов, совокупный объём декодированных байтов потоков, коэффициент раздувания на поток и число страниц проверяются на соответствие пределам политики. Документ, превышающий пределы, отклоняется, а не обезвреживается. Отклонение и обезвреживание сообщаются отдельно.
  3. Обнаружение. ThreatDetector::detect сканирует каждый объект и каталог трейлера на типы угроз политики. Неразбираемые объекты записываются как находки ThreatType::UnparseableObject, а не пропускаются.
  4. Фильтрация. Объекты с находками ставятся в очередь на удаление. Каталог документа никогда не удаляется как целый объект. Находки на уровне каталога (OpenAction, AdditionalActions, NamedJavaScript) вместо этого устраняются удалением ключей.
  5. Очистка ссылок. Каждая косвенная ссылка на удалённый объект заменяется на null при сериализации.
  6. Пересборка. 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/enterprise 3.1.0.
  • Всё выполняется в рамках процесса на вашем хосте. Во время обезвреживания сетевой доступ не происходит.
  • CdrPolicy и DetectedThreatfinal readonly; чтобы изменить пределы, сконструируйте новый экземпляр политики.
  • CdrEngine конструирует свои детектор и построитель внутренне. ThreatDetector и CdrRebuilder остаются напрямую пригодными для поэтапных конвейеров, которые поставляют собственный PdfReader.
  • Параметр $policy метода CdrRebuilder::rebuild сейчас зарезервирован; исходный код документирует его как сохранённый для совместимости мест вызова и будущих настроек сериализации на уровне политики.
  • Выход структурно воспроизводим, но не побитово: перегенерированный /ID отличается при каждом запуске, когда источник его нёс.
  • Тип результата CdrResult (возвращаемое значение sanitize()) охвачен поведенчески выше; его поля — public readonly, с hadThreats() и threatCount() в качестве удобных методов.

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