このページはコミュニティによって翻訳されたもので、最新ではない可能性があります。参照用のバージョンをご覧ください。
このページはコミュニティによって翻訳されたもので、最新ではない可能性があります。参照用のバージョンをご覧ください。
このページはコミュニティによって翻訳されたもので、最新ではない可能性があります。参照用のバージョンをご覧ください。
このドキュメントでは、FrankenPHP の信頼モデルについて説明します。具体的には、どの入力が信頼され、どの入力が信頼されず、その境界がどこにあるかです。 これは、FrankenPHP が提供する PHP アプリケーションではなく、FrankenPHP そのものに関するセキュリティ監査や自動スキャナーの検討に役立つことを意図しています。
ここで参照されている内部メカニクス(スレッド、CGO 境界、環境サンドボックス)については、内部構造を参照してください。 長期間実行されるプロセスにおける状態の永続性については、ワーカーモードを参照してください。
FrankenPHP は、4 つの異なるアクターを持つスタックで動作します。
| アクター | 信頼度 | 注記 |
|---|---|---|
| リモートクライアント | 信頼されていない | HTTP リクエスト(メソッド、URI、ヘッダー、クッキー、ボディ、アップロード)は、汚染された入力の主要なソースです。 |
| オペレーター | 信頼されている | デプロイ設定を提供します。具体的には、Caddyfile、環境変数、php.ini、インストールされている PHP 拡張機能と Caddy モジュール、およびアプリケーションコード自体です。 |
| PHP アプリケーションコード | 由来によって信頼されている | オペレーターによってデプロイされるため、FrankenPHP は攻撃者から提供されたコードを実行することはありませんが、このコードは信頼されていないリクエストデータを消費します。 |
| FrankenPHP (Go + C) | 信頼できるコンピューティングベース | PHP を組み込み、データの入出力を行い、リクエストとスレッドを分離します。本ドキュメントでは、FrankenPHP 自身の欠陥に焦点を当てています。 |
これは最も重要な区別であり、「PHP を信頼すべきか否か?」という混乱のほとんどを解消するものです。
$_GET、$_POST、$_COOKIE、$_FILES、$_SERVER、php://input)は、他の PHP SAPI と同様に信頼されていません。これをサニタイズするのはアプリケーションの仕事です。したがって、「PHP から来るものは信頼できる」というはコードについては真であり、「SAPI は信頼されていない入力を運ぶ」というのはデータについては真です。この 2 つは矛盾しません。 FrankenPHP の役割は、その汚染されたデータを忠実に運び、あるリクエストのデータが別のリクエストに漏洩するのを防ぐことです。
信頼できるコンピューティングベースには 3 つの役割があります。FrankenPHP のセキュリティ上の欠陥は、そのいずれかに存在します。
php://input にマッピングし、PHP の出力とヘッダーをクライアントに返送します。その際、インジェクション(ヘッダー/CRLF インジェクション、リクエスト密輸、誤ったファイルの実行)を引き起こさないようにします。これらは FrankenPHP が所有する領域です。ここでの脆弱性は FrankenPHP の脆弱性となります。
cgi.go、frankenphp_register_server_vars):$_SERVER、REMOTE_ADDR、SCRIPT_NAME、PATH_INFO、およびその他の CGI 変数をリクエストから構築します。split_path (デフォルトでは .php) で SCRIPT_NAME / PATH_INFO に分割され、その後 sanitizedPathJoin (filepath.Join(root, filepath.Clean("/"+reqPath))) を使用してドキュメントルートに結合されます。これにより、SCRIPT_FILENAME がドキュメントルートから逸脱するのを防ぎます(パストラバーサル)。また、php_server ディレクティブは、既存のファイルまたはフロントコントローラーにリクエストをルーティングするデフォルトの try_files リライトを設定し、誤ったファイルを実行するという従来の PHP-FPM の落とし穴を軽減します。$_GET、$_POST、$_COOKIE、$_FILES、$_SERVER、$_REQUEST をリセットし、$_SESSION(さもなければリクエスト間で漏洩する)および error_get_last() と libxml_get_errors() によって返されるエラー、http_get_last_response_headers() によって返されるヘッダー、strtok() の状態、output_add_rewrite_var() によって追加された変数を明示的にクリアします。しかし、$_ENV はリセットされず、putenv() による書き込み、static 変数、クラスの静的プロパティ、グローバル変数、およびランタイムエンジン設定(ini_set()、デフォルトのストリームコンテキスト、デフォルトのタイムゾーン、作業ディレクトリなど)は、同じスレッド上のリクエスト間で永続化します。その状態に残されたリクエストまたはユーザー固有のデータは、その後のリクエストに漏洩する可能性があります(ワーカーモードを参照)。frankenphp_putenv() / frankenphp_getenv() はスレッドローカルな sandboxed_env 上で動作します。putenv() による書き込みはそのサンドボックス内に留まり、プロセスグローバルな OS 環境には決して到達しません。そのため、あるリクエストによって設定された秘密が子プロセス(proc_open、exec など)、Go/Caddy 側、または他のリクエストに漏洩することはありません。そのような変数を見る必要がある子プロセスには、proc_open() または exec() の環境引数を通じて明示的に与える必要があります(内部構造を参照)。C.CString() / free() のライフタイム。localhost:2019 でリッスン)を通じて公開される /frankenphp/workers/restart および /frankenphp/threads エンドポイント。このエンドポイントを localhost 以外に公開するかどうかはオペレーターの判断です。X-Forwarded-* ヘッダーは常に汚染された $_SERVER['HTTP_X_FORWARDED_*'] 値として PHP に到達します。これらは、trusted_proxies が設定されている場合にのみ、実際のクライアント IP とスキームを導出するために信頼されます。request_body_timeout)を適用します。これにより、各読み取り前にデッドラインがリセットされるため、任意のサイズの安定したアップロードは成功し、停止したものは切断されてスレッドが解放されます。FrankenPHP に影響を与えるセキュリティ問題の報告方法については、SECURITY.md を参照してください。