¿Cuándo y por qué no funcionan los desinfectantes XSS con codificación doble?

22

He leído en diferentes sitios sobre diferentes formas de evitar los desinfectantes XSS, como caracteres especiales de codificación doble como /<>:"' , o que emplean diferentes esquemas de codificación.

Sin embargo, la mayoría de estos sitios no explican por qué estos ataques pueden funcionar y en qué casos. Por ejemplo, sé que los navegadores modernos codifican los caracteres especiales de la URL, mientras que cURL no hace eso; por lo tanto, no puede crear un PoC usando cURL (o Burp Proxy).

¿Puede alguien dar una explicación muy detallada sobre cómo los navegadores codifican y manejan los datos de entrada (tanto POST como GET) y cómo una aplicación web típica (PHP) maneja estos? Desde mi pequeña experiencia en PHP (mientras estaba en la universidad) solo estaba accediendo a parámetros como $_POST["query"] sin siquiera pensar en la codificación, las prácticas de seguridad, etc.

    
pregunta XII 08.05.2018 - 19:29
fuente

1 respuesta

31

Veamos este ejemplo de carga útil (A), codificada una vez (B) y dos veces (C):

A. <script> alert(1) </script>
B. %3Cscript%3E alert(1) %3C%2Fscript%3E
C. %253Cscript%253E alert(1) %253C%252Fscript%253E

La codificación doble se puede usar para omitir los filtros XSS cuando diferentes partes de la aplicación realizan diferentes suposiciones acerca de si una variable está codificada o no. Por ejemplo, considere el siguiente código vulnerable:

$input = htmlentities($_GET["query"]);
echo urldecode($input);

Este código bloquearía la carga útil si fuera solo codificado (como en B). La URL de PHP decodifica las variables GET para usted de forma predeterminada (convirtiendo B en A), por lo que < y > se pasarían a htmlentities que las neutraliza. Sin embargo, si en cambio envías C, la URL descodificada a B pasaría a través de htmlentities sin cambios. Ya que se vuelve a decodificar la URL antes de que se haga eco, se convierte en la peligrosa carga útil A.

Entonces, el error aquí es que hay otra capa de URL que decodifica después de el filtro XSS. Cuando las dos líneas están una junto a la otra de esta manera, el problema es bastante obvio. Pero estas dos cosas pueden estar en módulos separados que hacen que sea difícil de detectar. Ya que es difícil hacer un seguimiento de qué cadenas están codificadas en la URL, es tentador simplemente incluir una decodificación adicional para estar seguro, después de todo, generalmente no afecta a los datos no codificados.

El manual de PHP advierte sobre esto:

  

Advertencia: los superglobals $_GET y $_REQUEST ya están descodificados. El uso de urldecode() en un elemento en $_GET o $_REQUEST podría tener resultados inesperados y peligrosos.

En mi opinión, el manual no es lo suficientemente prudente aquí: descodificar cualquier dato no confiable después de filtrar por XSS es peligroso, sin importar de dónde provenga. ¡Tenga mucho cuidado con la modificación de sus datos después de haberlos filtrado!

Para obtener más información, consulte OWASP .

    
respondido por el Anders 08.05.2018 - 20:49
fuente

Lea otras preguntas en las etiquetas