
CakePHP 5.4.2 — высокий — удалённый — прокси — trustedProxies доверяет X-Forwarded-* с любого REMOTE_ADDR
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-trusted-proxies
Класс: Обход HTTPS-редиректа / подмена IP и хоста Доступ: Удалённый
CakePHP 5.4.2 (887b641) — Cake Software Foundation
HttpsEnforcerMiddleware с trustedProxies => ['10.0.0.1'] вызывает setTrustedProxies, который устанавливает trustProxy = true и никогда не сравнивает список с REMOTE_ADDR. После этого scheme(), host() и clientIp() доверяют подконтрольным атакующему заголовкам X-Forwarded-Proto / X-Forwarded-For / X-Forwarded-Host / X-Real-IP.
Middleware по умолчанию имеет trustedProxies равным null и не включает это поведение. Уязвим документированный сценарий настройки балансировщика нагрузки. Неаутентифицированный HTTP-клиент, не являющийся указанным прокси, может обойти HTTPS-редирект и подменить IP клиента и Host.
| ID | CVE пока нет |
| Класс | Обход HTTPS-редиректа / подмена IP и хоста |
| Доступ | Удалённый (неаутентифицированный HTTP; в приложении задан trustedProxies) |
| CWE | CWE-441, CWE-346 |
| CVSS | Высокий: 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 | GET / по HTTP с X-Forwarded-Proto: https | Доказано в лаборатории. 200, scheme=https, свидетельство в JSON |
Подмена 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 |
Обход IP-ACL / ограничения скорости, привязанных к clientIp() | Та же подмена | Выведено. Значение по умолчанию remote_addr в RateLimitMiddleware — это не данная ошибка |
| Отрицательный контроль | Те же forwarded-заголовки на /control (без trustedProxies) | Доказано в лаборатории. Всё ещё 301 на https |
Закрыто по этому остатку: значение по умолчанию trustedProxies => null; сам REMOTE_ADDR в лаборатории всё ещё является IP моста Docker (192.168.208.1, а не указанный 10.0.0.1). Не RCE. Не ошибка с cookie-jar.
Я зафиксировал 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-адреса позже используются как array_diff по цепочке XFF, а не как проверка подключающегося узла.
Уже зафиксированные ошибочные пути: считать middleware по умолчанию этим остатком (это не так); называть x-forwarded-for в RateLimitMiddleware той же ошибкой (в 5.4.1 bakery уже перевёл это значение по умолчанию на remote_addr); утверждать, что сам REMOTE_ADDR был подменён. Театр: reverse shell.
python3 cakephp-trusted-proxies-Abraxas-Labs.py
или
cd lab
./run.sh
Composer cakephp/cakephp 5.4.2 в PHP 8.3. Крошечное приложение: / использует trustedProxies => ['10.0.0.1']; /control — нет. Loopback HTTP на 127.0.0.1:19430.
/ без forwarded-заголовков -> 301 https./control с proto/for/host/real-ip -> 301 https./ с X-Forwarded-Proto: https -> 200, scheme https, trust_proxy=true, REMOTE_ADDR не равен 10.0.0.1./ с XFF + Host -> client_ip=203.0.113.50, host=spoof.invalid./ с 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-заголовкам только тогда, когда REMOTE_ADDR входит в список доверенных прокси (Symfony isFromTrustedProxy()). Пустой список не должен включать доверие.
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/ServerRequest.php · src/Http/Middleware/HttpsEnforcerMiddleware.phpGNU Affero GPL v3.0. См. LICENSE. Только loopback-лаборатория. Без гарантий.