コンテンツにスキップ

CodeIgniter 4 上の NextPDF のセキュリティと運用

このページでは、この統合が防がなければならない脅威を一覧します。 パッケージのソースに含まれる制御を示します。 安全なデプロイのための運用ルールを示します。

攻撃者が影響を及ぼし得る経路は 3 つあります。

  1. キュージョブのペイロード。 キューはジョブデータを保存します。 ブローカーにアクセスできる攻撃者は、そのデータを変更できます。 これは、デシリアライズされた信頼できない入力です。
  2. レスポンスのファイル名。 ユーザーはダウンロードのファイル名を指定できます。 不正な名前は、ヘッダー内容の注入につながる可能性があります。
  3. 設定のパス。 フォントパスと署名パスは設定から取得されます。 不正なパスは、意図しない場所への読み書きにつながる可能性があります。

キュージョブは、ペイロードをデシリアライズされた信頼できないデータとして扱います。 OWASP ASVS は、デシリアライズされた信頼できないデータに対して安全な入力処理を求めています(ASVS V1.5.2)。

以下は GeneratePdfJob で検証済みの制御です。

  • ビルダーは空でない文字列でなければなりません。 ジョブはそれ以外の型を拒否します。
  • ビルダーはパターン App\PdfBuilders\<Class>::<method> に一致しなければなりません。 ジョブは、それ以外の名前空間、プレーン関数、接頭辞や接尾辞の付いたペイロードを拒否します。
  • ビルダーは呼び出し可能でなければなりません。 ジョブは、パターンには一致しても解決(resolve)できない文字列を拒否します。

これらのルールは、改ざんされたキューペイロードによる任意コードの実行を防ぎます。 パッケージのテストでは、拒否される各ケースを検証しています。

ジョブはファイルをディスクに書き込みます。 OWASP ASVS は、アプリケーションがファイル操作のためにファイルパスを生成する際、安全なパス処理を求めています(ASVS V5.3.2)。

以下は GeneratePdfJob で検証済みの制御です。

  • 出力パスは空でない文字列でなければなりません。
  • ジョブはパスを正規化します。 どのチェックよりも前に、... のセグメントを解決し、区切り文字を変換します。
  • 正規化されたパスは WRITEPATH/pdfs/ の内側になければなりません。 ジョブは、名前の接頭辞を共有する兄弟ディレクトリ(pdfs-evil/)を拒否します。
  • パスは .pdf で終わらなければなりません(大文字・小文字を区別しません)。

これらのルールは、改ざんされたペイロードによる任意ファイルの書き込みを防ぎます。

PdfResponse は、すべての PDF レスポンスに固定された一連のヘッダーを付与します。

ヘッダー
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Content-Security-Policydefault-src 'none'
X-Robots-Tagnoindex, nofollow
Referrer-Policyno-referrer
Cache-Controlprivate, max-age=0, must-revalidate

ファイル名は、ヘッダーへ渡される前にサニタイズされます。 パッケージは、パス区切り文字、null バイト、CR/LF を除去します。 引用符付き形式にするため、二重引用符をエスケープします。 非 ASCII の名前には、RFC 5987 の filename*=UTF-8''… パラメーターを追加します。 空の名前は document.pdf になります。

フォントレジストリは、ストリームラッパー(://)または null バイトを含む fontsPath を拒否します。 実行時エラーを発生させます。 これにより、php://phar:// のようなラッパー経由のパスを防ぎます。

CodeIgniter 4 には PSR-11 コンテナーがありません。 代わりに Services ロケーターを使用します。 PSR-11 §1.3 は、サービスロケーターパターンを避けるべきものとして扱います(助動詞 SHOULD NOT)。 パッケージは、ロケーターの露出範囲を小さく保ちます。 各サービスを 1 つの名前付きファクトリーメソッドとして提供します。 サービスはコントローラー境界で解決します。 具体的なオブジェクトを内部へ渡します。 Services クラスをドメインコードに渡さないでください。

署名サービスはデフォルトで無効です。 signature.enabledtrue で、かつ signature.certificate が空でない場合にのみ有効になります。 パッケージのデフォルト署名レベルは B-B です。 NextPDF Pro は B-B ベースライン署名を提供します。 長期検証は、別の Enterprise 機能です。 これは本ページではなく、Premium リファレンスで説明されています。

運用ルール:

  • 証明書ファイルと鍵ファイルはソース管理の外に置いてください。 これらは .env またはシークレットマネージャー経由で渡してください。
  • 本番環境では tsa.allow_insecure_httpfalse のままにしてください。 平文の TSA チャネルは許容されません。
  • TSA が安定した鍵を公開している場合は、tsa.pinned_public_keys を設定してください。 tsa.warn_on_key_rotationtrue のままにしてください。
  • 鍵ファイルへの読み取りアクセスは、アプリケーションユーザーに限定してください。
  • 解決されたすべてのバージョンを composer.lock で固定してください。
  • ワーカーを実行するアプリケーションでは、codeigniter4/queue を必須依存関係にしてください。
  • キューワーカーを低権限のユーザーとして実行してください。 書き込みアクセスは WRITEPATH/pdfs/ のみに付与してください。
  • ワーカーには、Web 層と同じ NextPDF 拡張を用意してください。 署名付き PDF には、ワーカー環境に NextPDF Pro または Enterprise が必要です。
  • PDF をビルドするすべてのランタイムで、mbstring 拡張と zlib 拡張があることを確認してください。
  • レスポンスヘッダーがリバースプロキシを通過しても維持されることを確認してください。
  • PDF 生成をコンテキスト付きでログに記録してください。 証明書マテリアルや鍵のパスワードをログに記録しないでください。
  • キューペイロードの処理は OWASP ASVS V1.5.2 に準拠します。
  • キュー出力パスの処理は OWASP ASVS V5.3.2 に準拠します。
  • ロケーターの設計は PSR-11 §1.3 のガイダンスに従っています。

NextPDF コアは Apache-2.0 です。 署名のトラストアンカーと TSA の堅牢化は、NextPDF Pro または Enterprise がインストールされている場合に適用されます。 CodeIgniter パッケージは対応するサービスメソッドを公開しますが、対応する Premium パッケージがインストールされるまでは null を返します。 </get-license/?intent=codeigniter-signing> を参照してください。

  • /integrations/codeigniter/production-usage/ — 正しいキューの登録とディスパッチ。
  • /integrations/codeigniter/configuration/ — 署名、TSA、およびパスキー。
  • /integrations/codeigniter/troubleshooting/ — 検証済みの拒否メッセージ。
  • /integrations/codeigniter/overview/ — API の全体像。