コンテンツにスキップ
getnextpdf.com

Enterprise エディション

Content Disarm and Reconstruction — 詳細リファレンス

本ページは NextPDF\Enterprise\Security\Cdr モジュールの詳細リファレンスです。本モジュールは信頼できない PDF を無害化し、その安全なオブジェクトからクリーンなファイルを再構築します。パイプラインは、解析、受け入れ制御、脅威検出、フィルタリング、参照スクラビング、再構築の順です。出力は入力のセキュリティ投影であり、証拠用のコピーでは決してありません。ワークフローのガイダンスについては、まず CDR 機能ページ をお読みください。

本機能は NextPDF Enterprisenextpdf/enterprise)で提供され、Enterprise ティアのライセンスエンベロープによって有効化されます。この権限を持たないデプロイでは、本機能のクラスは読み込まれません。エディションの比較とライセンスの取得

シンボルパラメーターデフォルト動作戻り値スロー/失敗条件備考
CdrEngine::__constructなし内部のディテクターとリビルダーを構築CdrEngine宣言なし注入可能なコラボレーターなし
CdrEngine::sanitizestring $pdfData, ?CdrPolicy $policy = nullCdrPolicy::standard() の下で全パイプラインを実行CdrResult敵対的な入力でもスローしない。解析および受け入れの失敗は拒否結果を返す結果は拒否をサニタイズと区別して報告
CdrPolicy::__construct7 個のオプションの名前付きパラメーター、フェンス参照除去セットは空。allowUriActions は false。flattenIncrementalUpdates は true。制限はオブジェクト 100000 個、デコード後 256 MiB、10000 ページ、膨張率 1000.0CdrPolicy宣言なしfinal readonly。空の removeThreatTypes リストは何も検出しない
CdrPolicy::standardなしレガシー脅威セット。URI アクションを除去。デフォルト制限self宣言なし損失を伴う 7 個の Strip* ケースを除外
CdrPolicy::paranoidなしより厳しい制限のレガシー脅威セット:オブジェクト 50000 個、128 MiB、5000 ページ、膨張率 100.0self宣言なし損失を伴う 7 個の Strip* ケースを除外
CdrPolicy::permissiveなしJavaScriptLaunchActionNamedJavaScriptSubmitFormImportData のみを除去。URI アクションは保持self宣言なし信頼できるソース向け
CdrPolicy::allThreatTypesなし損失を伴う Strip* ケースを含む、すべての ThreatType ケースを返すlist<ThreatType>宣言なし明示的な最大ストリップのオプトイン
CdrPolicy::legacyThreatTypesなし7 個の Strip* ケースを除くすべてのケースを返すlist<ThreatType>宣言なしstandard()paranoid() のデフォルト除去セット
CdrPolicy::shouldRemoveThreatType $typeremoveThreatTypes に対するメンバーシップ判定bool宣言なしallowUriActionstrue のとき UriAction に対して false を返す
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宣言なし4 個のプロパティはすべて public readonly
ThreatType文字列バック列挙型20 個のケース:13 個のレガシーに加え、7 個のオプトイン Strip* ケースn/an/a以下のケース一覧を参照
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

13 個のレガシーケースがデフォルトの除去セットを構成します。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 アクション。allowUriActionstrue のとき抑制
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オプトインのサブタイプ:MovieSoundFileAttachment3DRichMediaScreen
ThreatType::StripOcgNonDefaultstrip-ocg-non-defaultオプトイン:/Usage または /Visibility キーを持つ /Type /OCG
ThreatType::StripDigitalSignaturesAtRebuildstrip-digital-signatures-at-rebuildオプトイン:/Type /Sig/FT /Sig/DSS/VRI、または /ByteRange
ThreatType::Strip3dAndRichMediastrip-3d-and-rich-mediaオプトインのサブタイプ:3DU3DPRCRMFRichMediaSoundMovie

CdrEngine::sanitize は順序付けられた 6 つのフェーズを実行し、敵対的な入力に対して決してスローしません。

  1. 解析。 解析の失敗は、admitted が false で解析エラーの拒否理由を持つ結果を返します。その場合、サニタイズ出力は空です。
  2. 受け入れ制御。 オブジェクト数、デコード後のストリームバイト合計、ストリームごとの膨張率、およびページ数がポリシー制限に照らして検査されます。制限を超えるドキュメントは、サニタイズされず拒否されます。拒否とサニタイズは区別して報告されます。
  3. 検出。 ThreatDetector::detect は、ポリシーの脅威タイプについてすべてのオブジェクトとトレーラーカタログをスキャンします。解析不能なオブジェクトはスキップされず、ThreatType::UnparseableObject の検出結果として記録されます。
  4. フィルタリング。 検出結果を持つオブジェクトは、除去のためにキューへ入れられます。ドキュメントカタログがオブジェクト全体として除去されることはありません。カタログレベルの検出結果(OpenActionAdditionalActionsNamedJavaScript)は、代わりにキーのストリッピングによって修復されます。
  5. 参照スクラビング。 除去されたオブジェクトへのすべての間接参照は、シリアライズ中に null へ置き換えられます。
  6. 再構築。 CdrRebuilder::rebuild は、番号を振り直したオブジェクト、古典的なクロスリファレンステーブル、および新しいトレーラーを持つ単一リビジョンの %PDF-2.0 ファイルを出力します。安全なストリームバイトはバイト単位で同一にコピーされます。再構築されたカタログは /OpenAction/AA/Names を削除し、/AA はすべてのオブジェクトから削除されます。

返される CdrResult は、再構築後のバイト列、除去された脅威のリスト、両方のバイトサイズ、受け入れフラグ、および拒否理由を公開します。ソースに解決可能な /Root があり、再構築後の出力でそれが失われた場合、エンジンは構造的に壊れたファイルを返す代わりに出力を拒否します。これはフェイルクローズドの保証です。admitted が true であることは、出力が依然としてドキュメントカタログ参照を保持していることを意味します。

増分更新が残ることは決してありません。再構築はすべてのポリシーの下で正確に 1 つのリビジョンをシリアライズするため、シャドウ形式の後付けリビジョンは構造上フラット化されます。バイト範囲が出力と一致しなくなるため、元のデジタル署名は再構築をまたいで有効なまま保たれることはできません。

アーキテクチャのレッドライン。 CDR はセキュリティ投影レイヤーであり、保存レイヤーではありません。出力を、法的な証拠保全、オリジナルとのハッシュ比較、またはアーカイブコピーに使用してはなりません。

  • null ポリシーは CdrPolicy::standard() に解決されます。デフォルトの空の removeThreatTypes で構築されたポリシーは、何も検出せず何も除去しません。
  • allowUriActionstrue に設定すると、そのケースが removeThreatTypes に含まれている場合でも UriAction の除去が抑制されます。
  • flattenIncrementalUpdates は本リリースでは宣言的です。再構築は、フラグを false に設定する permissive() を含むすべてのポリシーの下で、単一のリビジョンを出力します。
  • 膨張率のチェックは、生のストリーム長ゼロを 1 として扱うため、無からの膨張ストリームも依然として制限されます。デコード形式が保持されない場合、生のストリーム長が合計バジェットに算入されます。
  • ページ数の受け入れチェックはベストエフォートです。カタログまたはページツリーの読み取り失敗だけでは、ドキュメントを拒否しません。オブジェクト数と解凍バジェットは常に強制されます。
  • 生のストリーム長が整数の /Length エントリと一致しないオブジェクトは、再構築時にスキップされます(ポリグロット防御)。そのようなスキップされたオブジェクトへの参照は、ソースのオブジェクト番号を保持し、出力内で解決されない場合があります。sanitize() は検出可能な壊れた結果(/Root の欠落)を拒否しますが、低レベルの CdrRebuilder::rebuild() を直接駆動する呼び出し元は、出力構造と参照の整合性を自身で再検証する必要があります。
  • ソースのトレーラーが /ID を保持している場合、再構築されたトレーラーは元のものではなく、新たに生成されたランダムな /ID を保持します。/Info を含むその他のトレーラーエントリは引き継がれません。再構築されたトレーラーは、/Size、解決可能な場合の /Root、および再生成された /ID を保持します。
  • デコードされた名前とキーのバイトは、区切り文字、空白、および印字不能なバイトについて 16 進エスケープとともに再出力されるため、敵対的な名前が出力に辞書構文を注入することはできません。
  • 既知の名前値セット外の辞書キーの下にある文字列値は、保守的にリテラル文字列として出力されます。
  • CdrPolicy::legacyThreatTypes() は、将来の列挙ケースが 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 で提供されるサーフェスを文書化しています。
  • すべてがホスト上のプロセス内で実行されます。サニタイズ中にネットワークアクセスは発生しません。
  • CdrPolicyDetectedThreatfinal readonly です。制限を変更するには、新しいポリシーインスタンスを構築します。
  • CdrEngine は、そのディテクターとリビルダーを内部で構築します。ThreatDetectorCdrRebuilder は、独自の PdfReader を供給する段階的なパイプライン向けに、引き続き直接利用できます。
  • CdrRebuilder::rebuild$policy パラメーターは現在予約されています。ソースでは、呼び出し側の互換性と将来のポリシーごとのシリアライズ調整のために保持されていると文書化されています。
  • 出力は構造的に再現可能ですが、ビット単位で再現可能ではありません。再生成される /ID は、ソースがそれを保持していた場合、実行ごとに異なります。
  • 結果型 CdrResultsanitize() の戻り値)は上記で動作面から扱われています。そのフィールドは public readonly で、hadThreats()threatCount() を便宜的に備えています。

本ページは、外部から観測可能な動作とサポートされる公開 API サーフェスのみを文書化しています。内部の名前空間パス、ヘルパークラス、メカニズムテーブル、ランブックのファイル名、およびチケットのプレフィックスは対象外です。