
CakePHP 5.4.2 - 高 - リモート - プロキシ - trustedProxies が任意の REMOTE_ADDR からの X-Forwarded-* を信頼する
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-trusted-proxies
クラス: HTTPSリダイレクトバイパス / IP・ホスト偽装 到達範囲: リモート
CakePHP 5.4.2 (887b641) - Cake Software Foundation
trustedProxies => ['10.0.0.1'] を指定した HttpsEnforcerMiddleware は setTrustedProxies を呼び出し、これが trustProxy = true を設定し、リストを REMOTE_ADDR と比較することは一切ない。その後、scheme()、host()、clientIp() は攻撃者の X-Forwarded-Proto / X-Forwarded-For / X-Forwarded-Host / X-Real-IP を信用する。
デフォルトのミドルウェアは trustedProxies が null であり、これを有効化しない。 ドキュメント化されたロードバランサー構成が露出するケースである。リストに載っているプロキシではない未認証のHTTPクライアントが、HTTPSリダイレクトをスキップし、クライアントIPとHostを偽装できる。
| ID | CVE未割当 |
| クラス | HTTPSリダイレクトバイパス / IP・ホスト偽装 |
| 到達範囲 | リモート (未認証HTTP; アプリが trustedProxies を設定) |
| CWE | CWE-441, CWE-346 |
| CVSS | High: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N |
| 製品 | CakePHP |
| 影響を受けるバージョン | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| 認証 | なし。アプリが HttpsEnforcerMiddleware の trustedProxies を設定 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
trustedProxies を有効化したアプリ(典型的なリバースプロキシによるHTTPS強制)が必要。リストに載っているプロキシIPから接続する必要はない。
| 権限 | メソッド / シンク | ラボで実証済みか推測か |
|---|---|---|
| HTTPSリダイレクト / HSTSパスをスキップ | X-Forwarded-Proto: https を付けた GET / HTTP | ラボで実証済み。200、scheme=https、JSON内にwitness |
clientIp() を偽装 | X-Forwarded-For: 203.0.113.50 | ラボで実証済み。client_ip=203.0.113.50 |
host() を偽装 | X-Forwarded-Host: spoof.invalid | ラボで実証済み。host=spoof.invalid |
X-Real-IP 経由で偽装 | X-Real-IP: 198.51.100.9 | ラボで実証済み。client_ip=198.51.100.9 |
clientIp() をキーとするIP ACL / レート制限をバイパス | 同じ偽装 | 推測。RateLimitMiddleware のデフォルト remote_addr はこのバグではない |
| ネガティブコントロール | /control(trustedProxies なし)で同じ転送ヘッダー | ラボで実証済み。依然として https へ 301 |
この残存項目についてクローズ済み: デフォルトの trustedProxies => null; REMOTE_ADDR 自体はラボでは依然として Docker ブリッジIP(192.168.208.1 であり、リストの 10.0.0.1 ではない)。RCEではない。クッキージャーのバグでもない。
cakephp/cakephp 5.4.2 をピン留めした。ServerRequest::setTrustedProxies():
public function setTrustedProxies(array $proxies): void
{
$this->trustedProxies = $proxies;
$this->trustProxy = true;
$this->uri = $this->uri->withScheme($this->scheme());
}
HttpsEnforcerMiddleware は trustedProxies が非nullであるたびにこれを呼び出す。リストされたIPは後にXFFチェーンに対する array_diff として使用され、接続してきたピアのチェックとしては使用されない。
すでに記録済みの誤った道: デフォルトのミドルウェアをこの残存項目として扱うこと(そうではない); RateLimitMiddleware の x-forwarded-for を同じバグと呼ぶこと(5.4.1 の bakery はすでにそのデフォルトを remote_addr に移している); REMOTE_ADDR 自体が偽装されたと主張すること。茶番: リバースシェル。
python3 cakephp-trusted-proxies-Abraxas-Labs.py
または
cd lab
./run.sh
PHP 8.3 上の Composer cakephp/cakephp 5.4.2。小さなアプリ: / は trustedProxies => ['10.0.0.1'] を使用; /control は使用しない。127.0.0.1:19430 でのループバックHTTP。
/ -> 301 https。/control -> 301 https。X-Forwarded-Proto: https を付けて GET / -> 200、scheme https、trust_proxy=true、REMOTE_ADDR は 10.0.0.1 ではない。/ -> client_ip=203.0.113.50、host=spoof.invalid。X-Real-IP を付けて GET / -> client_ip=198.51.100.9。SUCCESS cakephp-trusted-proxies pin=5.4.2 how=app remote-addr=192.168.208.1 listed-proxy=10.0.0.1 proto-bypass=200 control-redirect=301 client-ip=203.0.113.50 host=spoof.invalid x-real-ip=198.51.100.9 CAKEPHP-TRUSTED-PROXIES-WITNESS
REMOTE_ADDR が信頼済みプロキシリストに含まれる場合にのみ転送ヘッダーを信用する(Symfony の isFromTrustedProxy())。空のリストは信頼を有効化してはならない。
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/ServerRequest.php · src/Http/Middleware/HttpsEnforcerMiddleware.phpGNU Affero GPL v3.0。LICENSE を参照。ループバックラボのみ。無保証。