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 .