Guarda questo payload di esempio (A), codificato una volta (B) e due volte (C):
A. <script> alert(1) </script>
B. %3Cscript%3E alert(1) %3C%2Fscript%3E
C. %253Cscript%253E alert(1) %253C%252Fscript%253E
È possibile utilizzare la doppia codifica per bypassare i filtri XSS quando diverse parti dell'applicazione applicano presupposti diversi se una variabile è codificata o meno. Ad esempio, considera il seguente codice vulnerabile:
$input = htmlentities($_GET["query"]);
echo urldecode($input);
Questo codice bloccherebbe il carico utile se fosse solo codificato singolo (come in B). L'URL PHP decodifica le tue variabili GET per te automaticamente (trasformando B in A), quindi <
e >
verrebbero passati a htmlentities
che li neutralizza. Tuttavia, se invece invii C, sarebbe l'URL decodificato in B che passerebbe attraverso htmlentities
invariato. Poiché è stato decodificato nuovamente dall'URL prima che venga echeggiato, si trasforma nel pericoloso carico utile A.
Quindi il bug qui è che c'è un altro livello di decodifica dell'URL dopo il filtro XSS. Quando le due linee sono una accanto all'altra in questo modo, il problema è abbastanza ovvio. Ma queste due cose possono essere in moduli separati che lo rendono difficile da rilevare. Poiché è difficile tenere traccia di quali stringhe sono codificate dall'URL, si è tentati di aggiungere una decodifica extra per essere sicuri, dopotutto di solito non influisce sui dati non codificati.
Il manuale PHP in realtà mette in guardia su questo:
Warning: The superglobals $_GET
and $_REQUEST
are already decoded. Using urldecode()
on an element in $_GET
or $_REQUEST
could have unexpected and dangerous results.
A mio parere, il manuale non è abbastanza prudente qui: decodificare i dati non attendibili dopo il filtraggio per XSS è pericoloso, indipendentemente da dove provenga. Stai molto attento a modificare i tuoi dati dopo averlo filtrato!
Per maggiori informazioni, vedi OWASP .