abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-trusted-proxies
技术分析文章:https://abraxaslabs.tech/research/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。
默认中间件的 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 路径 | 使用 X-Forwarded-Proto: https 发起 GET / HTTP 请求 | 实验验证。返回 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 |
绕过基于 clientIp() 的 IP ACL / 速率限制 | 同样的伪造方式 | 推断。RateLimitMiddleware 默认的 remote_addr 并非此漏洞 |
| 阴性对照 | 在 /control(未设置 trustedProxies)上发送相同的转发头 | 实验验证。仍返回 301 重定向至 https |
关于此遗留问题的结论:默认 trustedProxies => null;在实验环境中 REMOTE_ADDR 本身仍是 Docker 网桥 IP(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 非空时调用它。列出的 IP 随后被用作 XFF 链上的 array_diff,而不是对连接对端进行检查。
已记录的误判:将默认中间件视为这一遗留问题(并非如此);将 RateLimitMiddleware 的 x-forwarded-for 称为同一缺陷(5.4.1 bakery 已将该默认值改为 remote_addr);声称 REMOTE_ADDR 本身被伪造。表演环节:一个反向 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 不使用。回环 HTTP 位于 127.0.0.1:19430。
/ 无转发头 -> 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
仅当 REMOTE_ADDR 位于受信任代理列表中(Symfony 的 isFromTrustedProxy())时,才采信转发头。空列表不得启用信任。
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/ServerRequest.php · src/Http/Middleware/HttpsEnforcerMiddleware.phpGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境使用。不提供任何担保。