コンテンツにスキップ

compat-legacy のセキュリティと運用

アダプターは NextPDF エンジンのセキュリティモデルを継承し、レガシー TCPDF 6.2.13 に対して意図的な堅牢化をいくつか加えています。このページでは、何を利用でき、何を利用できないのかを、誇張せず正確に説明します。署名のセクションは注意してお読みください。対象範囲は意図的に狭く設定されています。

従来の TCPDF 6.2.13 の動作のうち 3 つは、安全性のために変更されており、安全でない形式に戻す設定はできません

懸念事項レガシー TCPDF 6.2.13アダプター
エラー処理Error()die() を呼び出してプロセスを終了させるError() による RuntimeException のスロー。観測・捕捉が可能で、プロセスの暗黙の強制終了なし。
HTML の実行エスケープハッチによってマークアップから PHP が実行されうるK_TCPDF_CALLS_IN_HTML 定数は false に固定。マークアップからの PHP 実行のトリガー不可。
直接出力Output() がアクティブな出力バッファにエコーする安全な出力先ブリッジ経由でのルーティング。呼び出し元が制御する出力バッファの汚染なし。

エラー処理の変更は、呼び出し元がプロセスの消失ではなく失敗を観測できなければならないという原則に従っています。OWASP ASVS 5.0 §16.5.3 は、アプリケーションが正常かつ安全に失敗し、フェイルオープン状態を防止すべきであると規定しています。die ではなく throw に変更したことで、この原則が適用されます。HTML の堅牢化により、コード実行のシンクが取り除かれます。古い動作に依存していたレガシーコードは、移行(/integrations/tcpdf-compat/migration/.)時に修正すべき欠陥として扱ってください。ピン留めされた条項ダイジェストはページのフロントマター citations にあります。

アダプターは TCPDF の SetProtection() を公開しています。これは NextPDF エンジンの標準セキュリティハンドラーに委譲されます。

  • 標準ハンドラーは AES-256 を使用します。レガシーの $mode パラメーターはシグネチャ互換性のために受け付けられますが、無視されます。このメソッドを通じて、より弱い暗号を選択する方法はありません。ストリクトモードが有効な場合、デフォルト以外の $mode では例外がスローされるため、移行時にそれを認識せざるを得なくなります(tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php でアサートされています)。
  • オーナーパスワードが指定されない場合、アダプターはユーザーパスワードを再利用するのではなく、暗号論的に強固なランダムなオーナーパスワードを生成します。これにより、ユーザーレベルのアクセス権を持つ者がドキュメントのオーナーレベルの制御権を取得することを防ぎます。
  • 証明書ベース(公開鍵)暗号化は、SetProtection() を通じては行われません。その $pubkeys パラメーターは無視されます。アダプターが公開している最新の公開鍵暗号化エントリーポイント(setPublicKeyEncryption())を使用してください。これはエンジンに委譲されます。

暗号化の動作は、ISO 32000-2 §7 に記述された標準セキュリティハンドラーを反映しています。この条項は、エンジンが使用する暗号化辞書のエントリーと AES-256 標準ハンドラーを定義しています。このドキュメントは、出力が「デフォルトで安全」または「改ざん不可能」であるとは主張しません。使用される暗号とオーナーパスワードの動作を記述しており、コードの動作もそれに一致します。ピン留めされた条項ダイジェストはページのフロントマター citations にあります。

examples/security-encryption.php
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();
$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);
$pdf->Cell(0, 10, 'Encrypted document');
// User password set; owner password auto-generated (strong, random).
$pdf->SetProtection([], 'user-secret');
$pdf->Output(__DIR__ . '/encrypted.pdf', 'F');

このセクションは文字どおりに読んでください。意図的に控えめな記述にしています。

  • TCPDF のレガシーな setSignature() および addEmptySignatureAppearance() メソッドは、コアエンジン上のアダプターでは実装されていません。デフォルトモードでは何も行わず、ストリクトモードでは TcpdfNotImplementedException をスローします。
  • デジタル署名は、このアダプターを通じて提供されるコアディストリビューションの機能ではありません。 ベースライン署名のサポートは、商用版の NextPDF エディションに限定されています。
  • 商用版が存在する場合、アダプターは、エンジンに委譲する最新の署名エントリーポイント(setSignatureV2())を公開します。そのデフォルトプロファイルは ベースライン(B-B) プロファイルです。
  • このドキュメントは、いずれのエディションについても、このアダプターを通じてタイムスタンプ付き、長期検証、またはアーカイブ署名プロファイルを生成するとは一切主張しません。具体的には、B-T、B-LT、または B-LTA の動作を主張しません。PAdES ベースライン仕様 §6.1 は、4 つの異なるベースラインレベル(B-B、B-T、B-LT、B-LTA)を定義しており、それぞれに固有の要件があります。B-B がベースラインレベルであり、上位レベル(タイムスタンプ、長期、アーカイブ)は、より要求の厳しい別個のプロファイルです。この互換性レイヤーのドキュメントで対象とするのは、B-B ベースラインのみです。上位レベルは明示的にスコープ外であり、ここではいずれのエディションについても主張しません。ピン留めされた条項ダイジェストはページのフロントマター citations にあります。
  • 「認証済み」「保証付き」「法的に有効」または「eIDAS 適格」といった署名に関する主張は、どこにも記載されていません。署名の正確性、トラストアンカーのポリシー、および法的有効性は、署名エディションと呼び出し元の PKI の責任であり、この互換性レイヤーの責任ではありません。

移行で署名が必要な場合は、別個のワークストリームとして扱ってください。商用版で最新の署名 API を採用し、生成された署名を独立した検証ツールで検証してください。TCPDF の setSignature() 呼び出しには依存しないでください。ここでは何もしません。

レガシーの setTimeStamp() メソッドはシグネチャ互換性のために受け付けられ、通知は発しますが、このアダプターを通じてタイムスタンプ付き署名を生成することはありません。

コンストラクターの pdfa フラグは、シグネチャ互換性のために受け付けられます。PDF/A アーカイブ適合性には、商用版の NextPDF エディションが必要です。アダプターは、エンジンに委譲する enablePdfA() を公開しており、必要なエディションが存在しない場合、エンジンは対処可能な構成エラーを返します。アダプターが PDF/A を主張しながら、非適合ファイルを暗黙に生成することはありません。

出力は常に PDF 2.0(ISO 32000-2)です。ISO 32000-2 §7.5.2 は、適合する書き込み側がドキュメントのバージョンを 2.0 と識別し、保存時にそれより古いバージョンへ下げないことを規定しています。したがって setPDFVersion() でより古いバージョンを下位ターゲットにすることはできません(/integrations/tcpdf-compat/method-coverage/ §4 を参照)。ピン留めされた条項ダイジェストはページのフロントマター citations にあります。

  • プロセス終了なし。 Error()die() ではなく例外をスローするため、レンダリングのエントリーポイントを try/catch でラップし、失敗をアプリケーションのエラー契約にマッピングしてください。レンダリングの失敗がリクエストを終了させると想定しないでください。
  • 出力バッファの安全性。 Output() は、S ではバイト列を返し、F ではファイルに書き込み、E では base64 の MIME ボディを返し、I/D ではエンジンの出力パス経由でルーティングします。ワーカーや HTTP ハンドラーでは S または F を優先し、レスポンスは呼び出し元側で制御してください — /integrations/tcpdf-compat/production-usage/. を参照してください。
  • ストリクトモードは本番環境向けの設定ではありません。 CI/監査ジョブに限定してください。本番環境のレンダリングパスで例外が発生すると、暗黙に劣化したパラメーターよりも悪い結果をもたらします。
  • 定数の衛生管理。 PDF_* / K_* 定数は、最初のアダプターを構築する前に定義してください。2 つの堅牢化されたフラグ(K_TCPDF_CALLS_IN_HTMLK_TCPDF_THROW_EXCEPTION_ERROR)は緩和できません。緩和を試みないでください。
  • ランダムなオーナーパスワード。 決定的なオーナーパスワードに依存する場合は、明示的に設定してください。そうでない場合、ドキュメントごとに強固なランダムなものが生成され、復元できません。
  • 画像メソッドでは、ストリームラッパーのパスはファイルシステムの読み取り前に拒否されます。画像タイプの検出(TcpdfImages::getImageFileType)は、あらゆる scheme:// パス — phar://php://、およびその他の PHP ストリームラッパー — をラッパーとして扱い、file_get_contents / getimagesize によるプローブをスキップして、拡張子のみの推論にフォールバックします。これにより、PHP 7.4 バックポートターゲットにおける phar メタデータのデシリアライズ経路が塞がれます。ラッパーパスの埋め込み自体はエンジンによって拒否されます。
  • それ以外の場合、アダプターは、エンジンが行う以上の検証やサニタイズを、画像メソッドや出力メソッドに渡されたファイルパスに対して行いません。呼び出し元から提供されたパスや URL は、アプリケーション境界で信頼できないものとして扱ってください。
  • HTML メソッドに渡された HTML は、TCPDF の HTML パーサーではなく、エンジンによってレンダリングされます。レガシーの PHP 実行シンクは塞がれていますが、呼び出し元から提供された HTML は依然として信頼できない入力として扱うべきです。
  • 暗号化は、標準ハンドラーに従って、保存時のドキュメントの機密性を保護します。これは、アプリケーションにおけるトランスポートセキュリティやアクセス制御の代替にはなりません。
  • /integrations/tcpdf-compat/method-coverage/ — SetProtection()setSignature() の正確な動作
  • /integrations/tcpdf-compat/configuration/ — 構成では緩和できない 2 つの堅牢化フラグ
  • /integrations/tcpdf-compat/production-usage/ — ワーカー、バッファ、失敗処理
  • docs/TCPDF_COVERAGE.md — 信頼できるカバレッジマトリクス
  • パッケージ NOTICE — 独立実装に関する記述