Cargando la página...

Vulnerabilidades XSS: PHP y $_SERVER[’PHP_SELF’]

Publicado por Daniel el 01/03/2009 en JavaScript - Nivel Intermedio

Tabla de contenidos

Avatar de

La tabla de contenidos pertenece al artículo completo y no al contenido parcial de cada página del mismo si fuese el caso.

Leer los comentarios.

Resúmen

Siguiendo un poco con la costumbre hoy vos a dejarles otro pequeño artí­culo sobre Seguridad en PHP y, más precisamente, sobre ataques y vulnerabilidades XSS. Durante el desarrollo de este texto voy a suponer leí­do el artí­culo anterior de Seguridad en PHP: Ataques XSS: el peligro de hacer echo $_GET['var'] por lo que no voy a explicar nuevamente los peligros que conlleva una vulnerabilidad XSS, los ejemplos para explotarlas, las formas de solucionar este problema ni otras cuestiones mencionadas en aquel texto.

Sobre el autor

Avatar de Daniel

Daniel tiene 24 años, vive en Argentina / Buenos Aires / La Matanza y su ocupación es Programador web.

Forma parte del club desde el 04/08/2007 habiendo estado en linea el 18/07/2010 12:47 por última vez.

Ha publicado 2 artículos en clubdesarrolladores con un promedio de valoración de 8.29 puntos. Puedes visitar su sitio web en http://www.formatoweb.com.ar/ajax

Estadísticas

  • Leido 1596 veces
  • Valorado 7.67 puntos

$_SERVER[’PHP_SELF’]



Hoy nos vamos a centrar en el análisis de la variable predefinida de PHP $_SERVER['PHP_SELF']. Para los que no están al tanto, esta variable retorna el valor del nombre de archivo del código PHP que se esté ejecutando actualmente, relativo a la raiz del sitio. Entonces si estoy visualizando a http://www.misitio.com/index.php la variable $_SERVER['PHP_SELF'] me arrojará /index.php. Dadas sus caracterí­sticas es muy común su uso dentro de etiquetas de ví­nculos a o dentro de etiquetas form en atributos action para hacer referencia al mismo script donde nos encontramos actualmente. El problema que muchos desconocen es que la variable $_SERVER['PHP_SELF'] es fácilmente manipulable por cualquier usuario y su mal uso puede representar un problema grave de seguridad, como veremos a continuación.

¿Por qué puede resultar peligroso el uso de esta variable?



Para responder a esta pregunta, lo mejor es valerse de un ejemplo muy común como ser el uso de ella dentro de una etiqueta a. Supongamos entonces a nuestro viejo amigo test.php realizado de la siguiente manera:

test.php

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Página vulnerable a ataques XSS</title>
</head>
<body>
<a href="<?php echo $_SERVER['PHP_SELF']; ?>?var=algo">Link</a>
</body>
</html>


La idea serí­a que $_SERVER['PHP_SELF'] nos retorne /test.php y el ví­nculo quede formado de esta manera:

<a href="/test.php?var=algo">Link</a>


Pues bien, con el uso de esta variable nos hemos ahorrado de colocar el nombre del script en el ví­nculo y además hemos conseguido que si el dí­a de mañana le cambiamos el nombre al script a nuevoTest.php no debemos modificar para nada la URL a la que apuntan las etiquetas a ya que nuestra tan útil variable nos retornarí­a el nuevo nombre.

El problema es que, como dice el tí­tulo de este artí­culo, $_SERVER['PHP_SELF'] se puede manipular; y cualquier usuario puede hacerlo. El punto es que la variable no se vale de la ruta real del script actual para retornar su valor, sino que toma su valor leyendolo de la URL que el usuario ha solicitado para acceder al script. Esto es algo que la documentación oficial de PHP no aclara y a mi entender sí­ deberia hacerlo. Sabiendo lo antedicho ¿qué pasarí­a si llamo a test.php de esta manera?:

test.php/">Link</a><script>alert("Sitio vulnerable")</script>


Si lo prueban podrán comprobar que sale un bonito cartelito (alert) que dice "Sitio vulnerable" (si no has leido el artí­culo que he recomendado al comienzo de este texto y te estás preguntando "¿qué peligro puede representar esto para mi?" te recomiendo con mucho énfasis que lo leas). Esto ocurre ya que la variable $_SERVER['PHP_SELF'] lee la URL y toma e imprime mediante el echo este valor:

/">Link</a><script>alert("Sitio vulnerable")</script>


Por lo cual realizando esta llamada maliciosa a test.php el HTML del ví­nculo quedará formado de esta manera:

<a href="/test.php/">Link</a><script>alert("Sitio vulnerable")</script>?var=algo">Link</a>


En la llamada a test.php lo que hay colocado entre la primer barra y antes de script corresponde al cierre de la etiqueta a de test.php para que el script JavaScript sea correctamente interpretado. Si colocáramos el JavaScript inyectado sin cerrar a podremos ver que no funciona, por eso se realiza previamente su cierre.

Esto por supuesto es un ataque "inocente", pero ustedes podrán haber comprobado en el artí­culo anterior que existen ataques realmente dañinos que se aprovechan de vulnerabilidades tan simples, inocentes y comunes como esta. La variable $_SERVER['PHP_SELF'] es muy peligrosa si es mal utilizada; y no solo por su posibilidad de ser vulnerable a ataques XSS, sino por todo mal uso que se desprenda de la idea incorrecta de que el usuario no tiene la posibilidad de influir sobre su valor.

Las posibles soluciones a esto ya han sido anteriormente discutidas en el artí­culo Ataques XSS: el peligro de hacer echo $_GET['var'].

Artículo original y de mi autoría

Si tiene alguna pregunta sobre éste artículo por favor deje un comentario y será respondido.

Descargas

No existen descargas asociadas

Comentarios

Sus comentarios son importantes.

Listado de comentarios

1
01
agosto
2009
avatar
Matias Perrone aportó:
El mismo problema puede pasar con el metodo POST, con la variable, para usar el mismo nombre $_POST['var'].

Lo probé (sin dañarlo) en varios sitios mios y de terceros... es increible la cantidad de agujeros de seguridad que existen hoy en los sitios. De hecho tengo clientes que han recurrido a mí para que les arregle las goteras de otros programadores menos experimentados, y tus artículos pueden echar alguna luz en el asunto.

Se puede salvar este problema, usando
$_SERVER['SCRIPT_NAME']
en vez de
$_SERVER['PHP_SELF']

Saludos!
Matias

Agregar un comentario

Debe estar identificado para agregar un comentario