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

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

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

PHP:
  1. <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?:

PHP:
  1. 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:

PHP:
  1. /">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:

PHP:
  1. <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

La licencia de este artí­culo la puedes ver aquí­.