
CakePHP 5.4.2 - 높음 - 원격 - 프록시 - trustedProxies가 모든 REMOTE_ADDR의 X-Forwarded-*를 신뢰함
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
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 | 높음: 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 없음)에 동일한 전달 헤더 적용 | 실습 입증. 여전히 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
Composer cakephp/cakephp 5.4.2 (PHP 8.3). 소규모 앱: /는 trustedProxies => ['10.0.0.1']를 사용하고, /control은 사용하지 않음. 127.0.0.1:19430에서의 루프백 HTTP.
/ (전달 헤더 없음) -> 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를 참조하세요. 루프백 실험 환경 전용입니다. 보증은 제공되지 않습니다.