Inyección - XSS
El Cross-Site Scripting, también conocido como XSS, es otro tipo de vulnerabilidad de inyección que provoca la ejecución de un script controlado por un atacante en el navegador de otro usuario. El XSS también puede considerarse una vulnerabilidad de inyección de HTML/JavaScript.
El impacto de una vulnerabilidad XSS depende en gran medida del contexto en el que exista. Va desde la capacidad de extraer información de la página en la que se ejecuta el script hasta la edición del estado de la página para realizar acciones como si fuera la víctima.
Veamos los tipos de XSS que puede encontrar.
Tipos de XSS
El XSS se puede dividir en varias categorías para facilitar su distinción. Se clasifican según cómo se entrega la carga útil (payload) y dónde se encuentra el punto de entrada.
Vector de entrega de la carga útil (Almacenado frente a Reflejado)
Existen dos formas en las que un atacante puede entregar una carga útil XSS:
- XSS almacenado: A través de datos controlados por el usuario almacenados, por ejemplo, en una base de datos donde los datos se muestran a otros usuarios
- XSS reflejado: A través de una carga útil proporcionada por el usuario que se pasa mediante la URL o la cadena de consulta a la que accede un usuario
La distinción fundamental es que un XSS reflejado suele depender de la interacción del usuario y solo afecta a quien abre el enlace con la carga útil maliciosa. Sin embargo, un XSS almacenado puede ejecutarse contra uno o varios usuarios simplemente al abrir ciertas páginas que procesan la carga útil.
Ubicación de la carga útil (DOM frente a no DOM)
La ubicación en la que se inyecta la carga útil determina si la vulnerabilidad se clasifica como una vulnerabilidad "DOM" o no. Esto se refiere a la distinción entre dónde se procesa la carga útil:
- XSS no DOM: La carga útil se procesa dentro del HTML, ya sea dentro de una etiqueta o de un atributo
- XSS DOM: La carga útil se procesa dentro de JavaScript, como una etiqueta `<script>` o un controlador de eventos como `onclick=""`
XSS - Primitivas de defensa
En esta sección, analizaremos los principios de las primitivas que sirven de base para la defensa contra XSS. Comprender los conceptos básicos es esencial, pero en la práctica, debería confiar en su biblioteca de plantillas para el 99% de la protección contra XSS.
Cuando escribe plantillas que se procesan en marcado o código que se ejecuta en un navegador, la clave para protegerse contra XSS es la *codificación*. La codificación, en este contexto, significa tomar una secuencia de caracteres y cambiarla a un formato que sea procesado de una manera específica por el intérprete.
Pero el tipo de codificación a utilizar depende de la ubicación o el contexto en el que se utilizarán los datos.
- Dentro de una etiqueta, como `<div>Entrada de usuario aquí</div>`: **Codificación HTML**
- Dentro de un atributo, como `<input placeholder="Entrada de usuario aquí"></input>`: **Codificación de atributos**
- Dentro de Javascript, como `<script>x = "Entrada de usuario aquí";</script>`: **Codificación JavaScript**
Algunos marcos de trabajo prescinden de la codificación como medio principal de defensa y, en su lugar, utilizan la higienización (sanitization) para limpiar un valor de cualquier contenido que pueda ser peligroso. Este es un proceso mucho más complejo con muchos casos excepcionales a considerar. No se recomienda implementar sus propias rutinas de higienización.
Ejemplos
Echemos un vistazo a algunos ejemplos en varios lenguajes para ver cómo funciona todo en la práctica.
C# - Inseguro: Razor
Si un objeto `IHtmlContent` va precedido de un `@`, el valor se coloca directamente en la plantilla sin ninguna codificación.
<!--- NO SEGURO: El htmlSnippet se interpretará sin ningún escape --->
@Html.Raw(htmlSnippet)
C# - Seguro: Razor
Por defecto, cualquier `string` precedido de un `@` se escapa como HTML en las plantillas Razor.
<!--- SEGURO: El htmlSnippet se escapará como HTML --->
@htmlSnippet
Java - Seguro: JSP
Al usar `c:out`, se realiza un escape XML por defecto (que puede cambiarse con la propiedad `escapeXml`), lo cual protege contra XSS en un contexto HTML, pero no en otros contextos.
<div><c:out value="<%= author %>" /></div>
Java - Seguro: (fnxml)
De forma similar al anterior, también puede llamar directamente a `fn:escapeXml`, que realizará un escape XML de la entrada proporcionada. Esto también solo protegerá en un contexto HTML.
<div>${fn:escapeXml(author)}</div>
Javascript - Inseguro: innerHtml de Angular
Al especificar la propiedad `innerHTML`, como su nombre indica, estará expuesto al riesgo de XSS debido a la desactivación de la codificación de salida.
<!--- NO SEGURO: El htmlSnippet se interpretará sin ninguna codificación --->
<p [innerHTML]="htmlSnippet"></p>
Javascript - Seguro: Interpolación de Angular
La interpolación de texto de Angular mediante llaves dobles (`{{` y `}}`) escapará su salida como HTML, protegiendo contra XSS.
<!--- SEGURO: El htmlSnippet se codificará y luego se interpretará --->
<p>{{htmlSnippet}}</p>
Javascript - Inseguro: React dangerousInnerHtml
Al especificar la propiedad `dangerouslySetInnerHTML`, tal como indica su nombre, te expones a un riesgo de XSS al desactivar la codificación de salida.
<!--- NO SEGURO: Como su nombre indica, el atributo dangerouslySetInnerHTML es peligroso ya que no escapa la salida --->
<div dangerouslySetInnerHTML={{ __html: htmlSnippet }} />;
Javascript - Seguro: React interpolado
La interpolación de texto en React mediante llaves (`{` y `}`) escapa el código HTML de su salida, protegiendo contra XSS.
<!--- SEGURO: El htmlSnippet se codificará y luego se interpretará --->
<div>{htmlSnippet}</div>
Python - Inseguro: Django
Si se utiliza el filtro `safe` en una plantilla de Django, se desactivará el escape automático de la salida, dejando de proteger contra XSS.
<!--- NO SEGURO: El htmlSnippet no se codificará en HTML --->
<div>{{ htmlSnippet | safe }}</div>
Python - Seguro: Django
La interpolación de texto en Django mediante llaves dobles (`{{` y `}}`) escapa el código HTML de su salida, protegiendo contra XSS.
<!--- SEGURO: El htmlSnippet se codificará en HTML --->
<div>{{ name }}</div>
Programación segura y práctica
Explore las directrices de programación segura para comprender y mitigar vulnerabilidades de software como el OWASP Top 10, y sumérjase en misiones de formación guiada para practicar en simulaciones de aplicaciones del mundo real.