Quando e perché bypassare disinfettanti XSS con doppia codifica funzionano?

22

Ho letto in diversi siti diversi modi per aggirare i disinfettanti XSS, come caratteri speciali di doppia codifica come /<>:"' , o utilizzando diversi schemi di codifica.

Tuttavia la maggior parte di questi siti non spiega perché questi attacchi potrebbero funzionare e in quali casi. Ad esempio, conosco i caratteri speciali dei browser moderni con codifica URL, mentre cURL non lo fa; quindi non puoi creare un PoC usando cURL (o Burp Proxy).

Qualcuno può fornire una spiegazione molto dettagliata su come i browser codificano e gestiscono i dati di input (sia POST che GET) e come una tipica applicazione web (PHP) gestisce questi? Dalla mia piccola esperienza in PHP (mentre ero all'università) stavo solo accedendo a parametri come $_POST["query"] senza nemmeno pensare a codifica, pratiche di sicurezza, ecc.

    
posta XII 08.05.2018 - 19:29
fonte

1 risposta

31

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 .

    
risposta data 08.05.2018 - 20:49
fonte

Leggi altre domande sui tag