
CakePHP 5.4.2 - Alta - Remota - Cookie - El cookie jar del cliente Http hace coincidir dominios como sufijo de regex
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-cookie-suffix
Clase: Fuga / plantado de cookies Alcance: Remoto
CakePHP 5.4.2 (887b641) - Cake Software Foundation
CookieCollection::findMatchingCookies usa preg_match('/' . preg_quote($domain) . '$/', $host). Eso es un sufijo de cadena, no una coincidencia de dominio RFC 6265. Una cookie para api.partner.com se envía a evilapi.partner.com. Una cookie para bank.com se envía a notbank.com.
Cookie::createFromHeaderString() también copia el Domain= de Set-Cookie sin verificar contra el host de la respuesta. addFromResponse desde attacker.test con Domain=victim.internal almacena esa cookie y luego la adjunta a victim.internal.
Una aplicación que usa Cake\Http\Client con el jar predeterminado en más de un host puede filtrar una cookie de sesión de un socio a un hermano con confusión de sufijo, o plantar una cookie en un host interno después de obtener una URL del atacante. other.com no coincide. Esto no es un bug de cookies del navegador. El cakephp/app estándar no llama a un segundo host por sí solo.
| ID | sin CVE aún |
| Clase | Fuga / plantado de cookies (coincidencia de dominio por sufijo regex) |
| Alcance | Remoto (la app usa el jar de Http Client entre hosts) |
| CWE | CWE-565, CWE-201 |
| CVSS | Alto: 8.2 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N |
| Producto | CakePHP |
| Afectado | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | la app usa Cake\Http\Client con el jar de cookies predeterminado entre hosts |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Requiere una aplicación que mantenga las cookies de Cake\Http\Client en más de un host (OAuth, webhooks, una URL proporcionada por el usuario, una segunda API).
| Privilegio | Método / sink | Probado en lab o inferido |
|---|---|---|
| Filtrar una cookie almacenada a un hermano con confusión de sufijo | CookieCollection::addToRequest para https://evilapi.partner.com/ después de una cookie con dominio api.partner.com | Probado en lab. La Cookie de la petición es sid=SECRET. RFC 6265 no coincidiría |
| Misma fuga para un sufijo registrable | Dominio de cookie bank.com, host de petición notbank.com | Probado en lab. La Cookie de la petición es sid=SECRET |
| Control negativo | Host de petición other.com | Probado en lab. Sin cabecera Cookie |
| Plantar una cookie para un host interno | addFromResponse de Set-Cookie: sid=x; Domain=victim.internal desde https://attacker.test/ | Probado en lab. El dominio almacenado es victim.internal; la siguiente petición a ese host envía sid=x |
| Fijación de sesión / sesión de socio robada en la siguiente llamada del Client | sid plantado o filtrado usado como sesión de API | Inferido. El lab se detiene en el oráculo de la cabecera Cookie |
| El envío al mismo host sigue funcionando | Dominio de cookie api.partner.com a host api.partner.com | Probado en lab. Esperado, no es un bug |
Cerrado sobre este remanente: other.com no coincide. Los jars de cookies del navegador no son este bug. Sin shell. No es RCE no autenticado en una app esqueleto.
Fijé cakephp/cakephp 5.4.2 tras GHSA-2qh5, GHSA-fxf7, GHSA-vjqc y la nota de filename= de 5.4.2. La coincidencia de cookies de Http Client es un sufijo regex:
$pattern = '/' . preg_quote($domain, '/') . '$/';
if (!preg_match($pattern, $host)) {
continue;
}
addFromResponse pasa el host de la petición solo como valor predeterminado. Un atributo Domain= de Set-Cookie lo sobrescribe y se almacena.
Caminos equivocados ya registrados: tratar esto como un bug de cookies del navegador; afirmar que other.com también coincide; inflar un oráculo de cabecera Cookie a ATO sin una app que use el jar entre hosts. Teatro: una reverse shell.
python3 cakephp-cookie-suffix-Abraxas-Labs.py
o
cd lab
./run.sh
Git clone del tag 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) en PHP 8.3. Oráculo HTTP en loopback en 127.0.0.1:19420. No se requiere un origen HTTP adicional; el oráculo ejecuta CookieCollection desde el pin.
sid=SECRET dominio api.partner.com. addToRequest https://evilapi.partner.com/ -> Cookie: sid=SECRET.https://other.com/ -> sin cabecera Cookie.https://api.partner.com/ sigue enviando sid=SECRET.bank.com -> https://notbank.com/ envía sid=SECRET.addFromResponse desde https://attacker.test/ con Set-Cookie: sid=x; Domain=victim.internal; Path=/. La siguiente https://victim.internal/ envía sid=x.SUCCESS cakephp-cookie-suffix suffix-leak=yes control-other=yes plant-domain=yes how=cakephp-5.4.2 CAKEPHP-COOKIE-SUFFIX-WITNESS
Coincidencia de dominio RFC 6265 (host === domain || str_ends_with($host, '.' . $domain)). Cookies solo de host cuando se omite Domain. Rechazar Domain que no coincida por dominio con el host de la petición. Rechazar sufijos públicos.
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/Cookie/CookieCollection.php · src/Http/Cookie/Cookie.phpGNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.