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

Enterprise エディション

コンテンツの無害化と再構築 (CDR)

NextPDF Enterprise は、コンテンツの無害化と再構築 (CDR) によって信頼できない PDF を無害化します。ファイルを解析し、受け入れ制限と照合し、危険な機能を検出して除去し、残ったオブジェクトから新しいファイルを再構築します。危険な機能とは、ビューアーが実行したり作用したりする可能性のあるアクティブコンテンツ — 埋め込みスクリプト、起動アクション、埋め込みファイル、リッチメディアなど — です。このページは挙動レベルの内容です。エンジンが何を受け入れ、何を除去し、何を再構築するか、そしてなぜ出力が証拠用コピーではないかを記載します。

CDR は破壊的かつ一方向の変換です。再構築された出力は入力のセキュリティ投影であり、保全されたコピーやハッシュが等価なコピーではありません。その境界はセキュリティとコンプライアンスに記載しています。

前提条件はフロントマターに記載されており、前提条件で繰り返します。

この機能は NextPDF Enterprise (nextpdf/enterprise) に同梱され、Enterprise ティアのライセンスエンベロープで有効化されます。そのエンタイトルメントを持たないデプロイでは、この機能のクラスはロードされません。NextPDF Core と NextPDF Pro は CDR を提供しません。エンジンはインプロセスで実行されます。信頼できないドキュメントは、お客様のホスト上で解析され再構築されます。エディションを比較してライセンスを取得

PDF は、ビューアーが実行したり作用したりできるアクティブコンテンツをサポートします。ECMAScript アクションは、ISO 32000-2 §12.6.4 に従い、PDF プロセッサにフィールド値や外観を変更しうるスクリプトを実行させます。起動アクションは、ISO 32000-2 §12.6.4 に従い、アプリケーションを起動するか、ドキュメントを開くか印刷します。name dictionary 内のドキュメントレベルスクリプトは、ISO 32000-2 §7.7.4 に従い、ドキュメントが開かれたときに自動的に実行されます。CDR はこれらのサーフェスを除去します。

エンジンは、順序付けられたパイプラインを実行します。

  1. 入力 PDF を解析します。
  2. 受け入れ制御 — ドキュメントが受け入れ境界 (オブジェクト数、ページ数、デコード済みストリームサイズ、および解凍爆弾入力に対抗するストリーム膨張率) 内にあることを検証します。制限を超えたドキュメントは、無害化されるのではなく拒否されます。拒否は無害化の結果とは明確に区別して報告されるため、お客様のエラー処理は両者を見分けることができます。
  3. 脅威を検出 — 構成された脅威タイプをスキャンします。
  4. フィルター — オブジェクトを安全なセットと除去されたセットに分割します。
  5. 参照スクラブ — 除去によって宙ぶらりんになったポインターをクリーンアップします。
  6. 再構築 — 安全なオブジェクトを新しい PDF にシリアライズします。

検出可能な脅威タイプには、埋め込みスクリプト (および不正な構造内のスクリプトを捕捉する積極的なスクリプト除去)、追加アクションおよびオープンアクションのトリガー、起動アクション、リモート go-to アクション、フォームの送信およびインポートデータアクション、埋め込みファイル、リッチメディアおよび 3 次元コンテンツ、ドキュメントレベルスクリプトの name tree、外部 Uniform Resource Identifier (URI) アクション、XML Forms Architecture データ、インタラクティブフォームフィールド、非デフォルトのオプショナルコンテンツレイヤー、およびデジタル署名オブジェクト (再構築はバイトレンジが一致しなくなるため必然的にこれを無効化します) が含まれます。解析できないオブジェクトは、それ自体が潜在的なバイパスとして扱われ、除去されます。

3 つのポリシーがデフォルトを設定します。

  • Standard — エンジンが検出可能な、構成されたアクティブコンテンツの脅威タイプを除去します。インクリメンタル更新は、署名シャドウイングに対抗するために常にフラット化され、このモードではそのフラット化は構成できません。
  • Paranoid — より厳格なリソース制限による、同じ除去です。
  • Permissive — 信頼できるソース向けです。スクリプトと起動アクションを除去しますが URI アクションは保持し、インクリメンタル更新のフラット化を構成可能にします。

CDR は、危険なキーをその場で削除するのではなく、安全と判断したオブジェクトから新しいファイルを再構築します。その許可リスト方式が、根幹となる決定です。検出器が認識しなかったオブジェクト — 解析できなかったものを含む — は出力に残らないため、未知の構造は拒否リストの隙間をすり抜けるのではなくフェイルクローズします。受け入れ制御が最初に実行されるのも同じ理由です。制限を超えた入力や解析不能な入力は、部分的に再構築されることなく、その場で拒否されます。その安全性の代償が保全性です。再構築はバイトレイアウトを変更し、署名を無効化し、脅威タイプが除去されるペイロードを削除します — これが、出力が証拠用コピーではなくセキュリティ投影である理由です。

設計背景: 信頼できない PDF の無害化: コンテンツの無害化と再構築

  1. NextPDF Core と Enterprise パッケージをインストールし、有効な Enterprise ライセンスを保持します。
  2. 入力の受け入れ境界 — 最大オブジェクト数、ページ数、デコード済みストリームサイズ、および膨張率 — を定義するか、プリセットポリシーの制限を使用します。
  3. ポリシーを決定します。一般的な信頼できない取り込みには standard、最も厳格な姿勢には paranoid、信頼できるソースにのみ permissive です。

ポリシーは不変であり、次を保持します。

  • 除去する脅威タイプ — 検出器がスキャンし、再構築器が除去するセット。
  • URI アクションの処理 — 外部 URI アクションを保持するかどうか。
  • インクリメンタル更新のフラット化 — standard と paranoid では常に有効。permissive では構成可能。
  • 受け入れ制限 — 最大オブジェクト数、ページ数、デコード済みストリームサイズ、および膨張率。これらは受け入れ境界であり、無害化の挙動ではありません。これらを超えるとドキュメントは拒否されます。
  1. 信頼できない PDF バイト列を読み込みます。
  2. ポリシー (standard、paranoid、または permissive) を選択するか、明示的な制限で 1 つ構築します。
  3. バイト列とポリシーを指定して、エンジンの無害化操作を実行します。
  4. 結果を検査します。受け入れられなかったと報告された場合は拒否理由を表面化させます。そうでない場合は、再構築されたバイト列と除去された脅威のリストを使用します。
  5. 再構築された出力は無害化された投影として扱い、入力の証拠用コピーやアーカイブコピーとして扱ってはなりません。
examples/enterprise/cdr-sanitize-guarded.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Enterprise\Security\Cdr\CdrEngine;
use NextPDF\Enterprise\Security\Cdr\CdrPolicy;
use NextPDF\Enterprise\Security\Cdr\CdrResult;
use Psr\Log\LoggerInterface;
final readonly class UntrustedPdfIntake
{
public function __construct(
private CdrEngine $engine,
private LoggerInterface $logger,
) {}
/**
* Sanitize an untrusted PDF and distinguish rejection from a clean rebuild.
*
* An over-limit document is rejected by admission control, not sanitized;
* the caller surfaces the rejection reason instead of trusting an empty
* output. The rebuilt bytes are a security projection, never an
* evidentiary copy of the input.
*
* @param string $pdfBytes The untrusted PDF bytes.
*
* @return CdrResult The sanitization result, including admission status.
*/
public function sanitize(string $pdfBytes): CdrResult
{
$result = $this->engine->sanitize($pdfBytes, CdrPolicy::standard());
if (! $result->admitted) {
$this->logger->warning('PDF rejected by CDR admission control', [
'reason' => $result->rejectionReason,
]);
return $result;
}
$this->logger->info('PDF sanitized', [
'removedThreats' => \count($result->removedThreats),
'originalSize' => $result->originalSize,
'sanitizedSize' => $result->sanitizedSize,
]);
return $result;
}
}
  1. 既知のアクティブコンテンツサーフェス (たとえばドキュメントレベルスクリプト) を持つサンプルを実行し、それが除去された脅威のリストに現れ、再構築された出力には存在しないことを確認します。
  2. 制限を超えたドキュメントを実行し、結果が拒否理由とともに受け入れられなかったと報告し、再構築されたバイト列が空であることを確認します。
  3. デジタル署名された入力について、再構築でその署名オブジェクトが除去されることを確認します — 再構築はバイトレンジが変わるため元の署名を無効化するので、古い署名オブジェクトは設計上除去されます。
  4. 再構築された出力をビューアーで開き、開いたときにスクリプトが実行されないことを確認します。
  • 証拠用ではありません。 再構築された出力は、破壊的かつ不可逆な投影です。法的な証拠保全、元のファイルとのハッシュ比較、またはアーカイブコピーとして使用しないでください。証拠用コピーが必要な場合は、元のファイルを別個の保管下に置いてください。
  • 無害化の前に受け入れ。 リソース制限は受け入れ境界です。制限を超えたドキュメントは、無害化されるのではなく拒否されます。制限を超えた入力がクリーンな再構築と取り違えられることが決してないよう、拒否を明確に区別して報告してください。
  • アクティブコンテンツは除去されます。 スクリプト、起動アクション、ドキュメントレベルスクリプトの name tree、埋め込みファイル、リッチメディアなどのサーフェスは除去されます — それらはビューアーが実行するであろうまさにそのアクションです (ISO 32000-2 §12.6.4 ECMAScript アクション。起動アクション。ドキュメントレベルスクリプト §7.7.4)。
  • 署名は再構築によって無効化されます。 再構築はバイトレイアウトを変更するため、元の署名はもはや検証できなくなります。署名オブジェクトは、誤解を招く形でそのまま残されるのではなく、除去されます。
  • 設計上ロッシーです。 埋め込みファイルのペイロード — Factur-X などのインボイス添付ファイルを含む — は、その脅威タイプが除去されると除去されます。CDR はセキュリティ投影であり、保全レイヤーではありません。

このページはドキュメントセキュリティに関わるものです。すべての規範的なソースはパラフレーズされており、規範的なテキストは複製されていません。

  • 解析失敗。 解析できないドキュメントは、部分的な再構築ではなく、解析エラー理由とともに受け入れられなかった結果を返します。
  • 制限を超えた入力。 結果は制限固有の理由とともに受け入れられなかったと報告します。再構築されたバイト列は空です。
  • 解析不能なオブジェクト。 解析できないオブジェクトは、サイレントに保持されるのではなく、潜在的なバイパスとして扱われ除去されます。
  • ベストエフォートのページ数。 ページ数の受け入れチェックはベストエフォートです。不正なカタログがあってもパイプラインはクラッシュしませんが、オブジェクト数とストリーム制限は依然として適用されます。

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