Una de las clases de vulnerabilidad más comunes en los sitios web se llama "Cross-Site Scripting" o "XSS". Las vulnerabilidades XSS son aquellas en las que un usuario puede hacer que se ejecute JavaScript. Hay varias variantes diferentes de vulnerabilidad XSS, con distintos grados de gravedad.
El problema de que un atacante pueda ejecutar JavaScript en las sesiones de otros usuarios es que entonces es posible que el atacante haga cualquier cosa en el sitio web que ven las víctimas. Esto incluye redirigir a las víctimas a sitios web externos, robar tokens de autenticación y monitorear los detalles de pago.
La forma más grave de vulnerabilidad XSS es la secuencia de comandos entre sitios "almacenada" o "persistente", aquí es donde es posible que un atacante cree una carga útil XSS y luego la envíe, de modo que se guarde en la base de datos. Con un exploit XSS guardado en la base de datos, es posible que afecte a otros usuarios durante un período de tiempo amplio.
Otra forma de Cross-Site Scripting es "Reflejada", este tipo no se guarda en ningún momento, sino que la carga útil se incluye en el navegador. Por lo general, este tipo de XSS es parte de los ataques de phishing, en los que un atacante intenta engañar a una víctima para que haga clic en un enlace malicioso.
En general, la mayoría de los ataques XSS tienen la carga útil enviada al servidor en algún momento, pero algunos ataques son puramente del lado del cliente, nunca se envían al servidor y, en cambio, solo afectan a JavaScript del lado del cliente. Esto se denomina XSS basado en DOM, ya que permanece en el modelo de objetos de documento de JavaScript, o DOM. Este tipo de vulnerabilidad es particularmente difícil de identificar y resolver porque el servidor nunca detecta las vulnerabilidades y, por lo tanto, no se pueden registrar.
Históricamente, la técnica de prevención contra las vulnerabilidades XSS es filtrar todos los datos enviados por el usuario, utilizando listas de bloqueo para rechazar cualquier mensaje con caracteres o palabras significativas en JavaScript. Esto tendió a conducir a una carrera armamentista para encontrar desvíos para el filtro y al mismo tiempo evitar algunas presentaciones legítimas de los usuarios. La solución correcta es utilizar entidades HTML para codificar los datos enviados por el usuario. con los módulos de entidades HTML habilitados, los caracteres se codifican automáticamente en un formato en el que el navegador sabe que debe mostrarlos como los símbolos correctos, pero no tratarlos como código.