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.
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'].
Sobre el artículo y aclaraciones
La licencia de este artículo la puedes ver aquí.