
CakePHP 5.4.2 - Alto - Remoto - Cookie - Il cookie jar del client Http confronta i domini come suffisso regex
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · cakephp-cookie-suffix
Write-up: https://abraxaslabs.tech/research/cakephp-cookie-suffix
Classe: Cookie leak / plant Portata: Remoto
CakePHP 5.4.2 (887b641) - Cake Software Foundation
CookieCollection::findMatchingCookies usa preg_match('/' . preg_quote($domain) . '$/', $host). Si tratta di un suffisso di stringa, non di un domain-match secondo RFC 6265. Un cookie per api.partner.com viene inviato a evilapi.partner.com. Un cookie per bank.com viene inviato a notbank.com.
Cookie::createFromHeaderString() copia inoltre Domain= di Set-Cookie senza alcun controllo rispetto all'host della risposta. addFromResponse da attacker.test con Domain=victim.internal memorizza quel cookie e successivamente lo allega a victim.internal.
Un'applicazione che usa Cake\Http\Client con il jar predefinito su più di un host può far trapelare un cookie di sessione di un partner verso un sibling confuso per suffisso, oppure impiantare un cookie su un host interno dopo aver recuperato un URL dell'attaccante. other.com non corrisponde. Non è un bug dei cookie del browser. Lo cakephp/app standard non chiama di per sé un secondo host.
| ID | nessuna CVE al momento |
| Classe | Cookie leak / plant (domain match per suffisso regex) |
| Portata | Remoto (l'app usa il jar di Http Client su più host) |
| 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 |
| Prodotto | CakePHP |
| Affetto | 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) |
| Auth | l'app usa Cake\Http\Client con il cookie jar predefinito su più host |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Richiede un'applicazione che conservi i cookie di Cake\Http\Client su più di un host (OAuth, webhook, un URL fornito dall'utente, una seconda API).
| Privilegio | Metodo / sink | Dimostrato in lab o dedotto |
|---|---|---|
| Far trapelare un cookie memorizzato verso un sibling confuso per suffisso | CookieCollection::addToRequest per https://evilapi.partner.com/ dopo un cookie con dominio api.partner.com | Dimostrato in lab. Il Cookie della richiesta è sid=SECRET. RFC 6265 non corrisponderebbe |
| Stesso leak per un suffisso registrabile | Dominio del cookie bank.com, host della richiesta notbank.com | Dimostrato in lab. Il Cookie della richiesta è sid=SECRET |
| Controllo negativo | Host della richiesta other.com | Dimostrato in lab. Nessun header Cookie |
| Impiantare un cookie per un host interno | addFromResponse di Set-Cookie: sid=x; Domain=victim.internal da https://attacker.test/ | Dimostrato in lab. Il dominio memorizzato è victim.internal; la richiesta successiva a quell'host invia sid=x |
| Session fixation / sessione di un partner rubata alla successiva chiamata Client | sid impiantato o trapelato usato come sessione API | Dedotto. Il lab si ferma all'oracolo dell'header Cookie |
| L'invio sullo stesso host funziona ancora | Dominio del cookie api.partner.com verso l'host api.partner.com | Dimostrato in lab. Atteso, non un bug |
Chiuso su questo residuo: other.com non corrisponde. I cookie jar dei browser non sono questo bug. Nessuna shell. Non è RCE non autenticata su un'app skeleton.
Ho fissato cakephp/cakephp 5.4.2 dopo GHSA-2qh5, GHSA-fxf7, GHSA-vjqc e la nota filename= della 5.4.2. Il matching dei cookie di Http Client è un suffisso regex:
$pattern = '/' . preg_quote($domain, '/') . '$/';
if (!preg_match($pattern, $host)) {
continue;
}
addFromResponse passa l'host della richiesta solo come default. Un attributo Domain= da Set-Cookie lo sovrascrive e viene memorizzato.
Vicoli ciechi già registrati: trattare questo come un bug dei cookie del browser; affermare che anche other.com corrisponde; gonfiare un oracolo dell'header Cookie fino all'ATO senza un'app che usi il jar tra host diversi. Teatro: una reverse shell.
python3 cakephp-cookie-suffix-Abraxas-Labs.py
o
cd lab
./run.sh
Git clone tag 5.4.2 (887b641de9f7aba06071f98f17edcbc573cbcf63) in PHP 8.3. Oracle HTTP loopback su 127.0.0.1:19420. Non è richiesta alcuna origine HTTP aggiuntiva; l'oracle esegue CookieCollection dal pin.
sid=SECRET dominio api.partner.com. addToRequest https://evilapi.partner.com/ -> Cookie: sid=SECRET.https://other.com/ -> nessun header Cookie.https://api.partner.com/ invia ancora sid=SECRET.bank.com -> https://notbank.com/ invia sid=SECRET.addFromResponse da https://attacker.test/ con Set-Cookie: sid=x; Domain=victim.internal; Path=/. Il successivo https://victim.internal/ invia sid=x.SUCCESS cakephp-cookie-suffix suffix-leak=yes control-other=yes plant-domain=yes how=cakephp-5.4.2 CAKEPHP-COOKIE-SUFFIX-WITNESS
Domain-match secondo RFC 6265 (host === domain || str_ends_with($host, '.' . $domain)). Cookie host-only quando Domain è omesso. Rifiutare Domain che non effettua il domain-match con l'host della richiesta. Rifiutare i suffissi pubblici.
887b641de9f7aba06071f98f17edcbc573cbcf63)src/Http/Cookie/CookieCollection.php · src/Http/Cookie/Cookie.phpGNU Affero GPL v3.0. Vedi LICENSE. Solo laboratorio loopback. Nessuna garanzia.