¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Evitar que el texto escrito se ejecute (XSS)

Después de esta lección: Puedo explicar y evitar el cross-site scripting escapando lo que se muestra.

Lección de 55 min3 comandosLaboratorio de DVWA: practica inyección SQL y XSS en la Damn Vulnerable Web Application

Un comentario que ejecuta algo

La web de una asociación de vecinos tiene un libro de visitas donde cualquiera deja un comentario. Alguien escribe un comentario con una etiqueta de script. Desde ese día, cada persona que abre la página ejecuta ese script sin saberlo.

La web guardó un texto y lo devolvió tal cual. El navegador no distingue el texto de un visitante del código de la propia web.

La regla única

Advertencia

Este laboratorio es una web insegura a propósito. Ataca solo tu copia privada, que no tiene salida a internet. Atacar un sistema que no es tuyo, o que no tienes permiso para probar, es delito en casi todos los países.

Al final de esta lección

Nota

Puedo explicar y evitar el cross-site scripting escapando lo que se muestra.

Palabras clave

PalabraQué significaEjemplo
HTMLel lenguaje con el que se describe una página
Scriptprograma pequeño que el navegador ejecuta dentro de una página
XSSfallo por el que el texto de otra persona se ejecuta como script en tu página
Escaparcambiar los signos especiales por texto inofensivo< pasa a &lt;
Cookiedato pequeño que el navegador guarda para una webPHPSESSID
HttpOnlymarca que impide a los scripts leer una cookie

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

El texto llega de dos formas

En el XSS reflejado, el texto viaja en la dirección y la página lo devuelve al momento. Hace falta que la víctima abra un enlace preparado.

En el XSS almacenado, la web guarda el texto y lo muestra a todos los que abren la página. No hace falta ningún enlace. Por eso es el más peligroso.

Ejemplo resuelto: reflejado y almacenado

TipoDónde queda el textoQuién lo sufre
ReflejadoEn la dirección y en la respuesta inmediataQuien abre el enlace preparado
AlmacenadoEn la base de datos de la webCada persona que abre la página

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Mira la web de tu laboratorio

Tu laboratorio tiene la web que vas a probar. Arráncalo y ejecuta estos tres comandos. Solo miran la página de acceso. No inician sesión y no escriben ningún script.

Las cookies importan. Un script que se ejecuta en una página puede leer sus cookies, salvo que la cookie lleve la marca HttpOnly.

¿Está la web en marcha?

Comando
curl -s -o /dev/null -w "%{http_code}\n" http://dvwa/login.php

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Las cookies que pone la web

Comando
curl -s -I http://dvwa/login.php | grep -i "^set-cookie"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

¿Cuántas cookies dicen HttpOnly?

Comando
curl -s -I http://dvwa/login.php | grep -ic httponly

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Qué te dicen las tres respuestas

El primero imprime 200. El segundo imprime dos líneas: una cookie llamada security y otra PHPSESSID, que es la sesión. El tercero imprime 0.

Ninguna cookie dice HttpOnly. Un script que lograra ejecutarse en esta web podría leer la cookie de sesión. Por eso el XSS suele acabar en sesiones robadas.

Escapar convierte los signos especiales en texto

El navegador toma < como el inicio de una etiqueta. Si la web escribe &lt; en su lugar, el navegador muestra el signo y no lo ejecuta.

Cinco signos se escapan: &, <, >, la comilla doble y la comilla simple. El & va primero. Si no, escaparías dos veces el & que acabas de crear.

Escapar un comentario

Código: python
comment = "<b>Hola</b> & gracias"
# Cambia el comentario y pulsa Run. El orden de los cambios importa.
safe = comment.replace("&", "&amp;")
safe = safe.replace("<", "&lt;")
safe = safe.replace(">", "&gt;")
print(safe)

Ejemplo resuelto: cinco signos

SignoSe escribePor qué importa
&&amp;Empieza todas las demás entidades
<&lt;Abre una etiqueta
>&gt;Cierra una etiqueta
"&quot;Cierra un valor entre comillas dobles
'&#39;Cierra un valor entre comillas simples

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un error frecuente

Advertencia

Mucha gente cree que basta con prohibir la palabra script. No es así. Hay otras etiquetas y atributos que ejecutan código, y las mayúsculas engañan a los filtros. Escapa al mostrar, siempre, con una sola función. No intentes adivinar qué texto es peligroso.

El escapado depende del sitio

El texto puede acabar en el cuerpo de la página, dentro de un atributo o dentro de un script. Cada sitio necesita su propio escapado.

Las cookies con HttpOnly y una política de contenido (CSP) son una segunda defensa. No sustituyen al escapado.

Para ir más allá: dentro de un atributo

El código de show-escape solo cambia tres signos. Pon el comentario dentro de un atributo: print('<img alt="' + safe + '">').

Prueba con el comentario x" onmouseover="y y pulsa Run. Explica qué atributo nuevo aparece, y añade el cambio que lo impide.

Sobre este laboratorio y su código: Laboratorio de DVWA: practica inyección SQL y XSS en la Damn Vulnerable Web Application

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.