
CakePHP 5.4.2 - Hoch - Remote - Proxy - trustedProxies berücksichtigt X-Forwarded-* von jeder REMOTE_ADDR
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-trusted-proxies
Klasse: HTTPS-Redirect-Bypass / IP-Host-Spoof Reichweite: Remote
CakePHP 5.4.2 (887b641) - Cake Software Foundation
HttpsEnforcerMiddleware mit trustedProxies => ['10.0.0.1'] ruft setTrustedProxies auf, was trustProxy = true setzt und die Liste nie mit REMOTE_ADDR vergleicht. Danach berücksichtigen scheme(), host() und clientIp() die vom Angreifer kontrollierten X-Forwarded-Proto / X-Forwarded-For / X-Forwarded-Host / X-Real-IP.
Die Standard-Middleware hat trustedProxies null und aktiviert dies nicht. Das dokumentierte Load-Balancer-Setup ist der exponierte Fall. Ein nicht authentifizierter HTTP-Client, der nicht der aufgelistete Proxy ist, kann den HTTPS-Redirect überspringen und die Client-IP sowie den Host spoofen.
| ID | noch keine CVE |
| Klasse | HTTPS-Redirect-Bypass / IP-Host-Spoof |
| Reichweite | Remote (nicht authentifiziertes HTTP; App hat trustedProxies gesetzt) |
| CWE | CWE-441, CWE-346 |
| CVSS | Hoch: 7.5 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N |
| Produkt | CakePHP |
| Betroffen | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | keine. App hat HttpsEnforcerMiddleware trustedProxies gesetzt |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Benötigt eine App, die trustedProxies aktiviert hat (typische Reverse-Proxy-HTTPS-Erzwingung). Muss sich nicht von einer aufgelisteten Proxy-IP aus verbinden.
| Privileg | Methode / Sink | Im Lab bewiesen oder abgeleitet |
|---|---|---|
| HTTPS-Redirect / HSTS-Pfad überspringen | GET / HTTP mit X-Forwarded-Proto: https | Im Lab bewiesen. 200, scheme=https, Witness in JSON |
clientIp() spoofen | X-Forwarded-For: 203.0.113.50 | Im Lab bewiesen. client_ip=203.0.113.50 |
host() spoofen | X-Forwarded-Host: spoof.invalid | Im Lab bewiesen. host=spoof.invalid |
Spoof via X-Real-IP | X-Real-IP: 198.51.100.9 | Im Lab bewiesen. client_ip=198.51.100.9 |
IP-ACL / Rate-Limit umgehen, das auf clientIp() basiert | Gleicher Spoof | Abgeleitet. RateLimitMiddleware-Standard remote_addr ist nicht dieser Bug |
| Negativkontrolle | Gleiche Forwarded-Header auf /control (kein trustedProxies) | Im Lab bewiesen. Weiterhin 301 zu https |
Geschlossen bei diesem Überbleibsel: Standard trustedProxies => null; REMOTE_ADDR selbst ist im Lab weiterhin die Docker-Bridge-IP (192.168.208.1, nicht die aufgelistete 10.0.0.1). Kein RCE. Kein Cookie-Jar-Bug.
Ich habe cakephp/cakephp 5.4.2 gepinnt. ServerRequest::setTrustedProxies():
public function setTrustedProxies(array $proxies): void
{
$this->trustedProxies = $proxies;
$this->trustProxy = true;
$this->uri = $this->uri->withScheme($this->scheme());
}
HttpsEnforcerMiddleware ruft dies auf, wann immer trustedProxies nicht null ist. Die aufgelisteten IPs werden später als array_diff auf der XFF-Kette verwendet, nicht als Prüfung des verbindenden Peers.
Bereits festgehaltene Irrwege: die Standard-Middleware als dieses Überbleibsel zu behandeln (ist sie nicht); RateLimitMiddleware x-forwarded-for als denselben Bug zu bezeichnen (5.4.1 bakery hat diesen Standard bereits auf remote_addr verschoben); zu behaupten, REMOTE_ADDR selbst sei gespooft worden. Theater: eine Reverse Shell.
python3 cakephp-trusted-proxies-Abraxas-Labs.py
oder
cd lab
./run.sh
Composer cakephp/cakephp 5.4.2 in PHP 8.3. Winzige App: / verwendet trustedProxies => ['10.0.0.1']; /control nicht. Loopback-HTTP unter 127.0.0.1:19430.
/ ohne Forwarded-Header -> 301 https./control mit proto/for/host/real-ip -> 301 https./ mit X-Forwarded-Proto: https -> 200, scheme https, trust_proxy=true, REMOTE_ADDR ist nicht 10.0.0.1./ mit XFF + Host -> client_ip=203.0.113.50, host=spoof.invalid./ mit X-Real-IP -> 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
Forwarded-Header nur berücksichtigen, wenn REMOTE_ADDR in der Trusted-Proxy-Liste steht (Symfony isFromTrustedProxy()). Eine leere Liste darf kein Vertrauen aktivieren.
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/ServerRequest.php · src/Http/Middleware/HttpsEnforcerMiddleware.phpGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.