ヒーロー背景(区切りなし)
ガイドライン

Inyección - XSS

El Cross-Site Scripting, también conocido como XSS, es otro tipo de vulnerabilidad de inyección que lleva a la evaluació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 existe la vulnerabilidad. Abarca desde poder extraer información de la página en la que se ejecuta el script hasta editar el estado de la página para realizar acciones como víctima en la página.

Veamos los tipos de XSS que puedes encontrar.

Tipos de XSS

El XSS se puede dividir en unos cuantos cubos para ayudar a distinguirlos. Se clasifican según la forma en que se entrega la carga útil y el punto de entrada.

Vector de entrega de carga útil (almacenado frente a reflejado)

Hay dos maneras en las que un atacante puede entregar una carga útil XSS:

  • XSS almacenado: Mediante datos controlados por el usuario almacenados, por ejemplo, en una base de datos en la que los datos se transmiten a otros usuarios
  • XSS reflejado: A través de una carga útil proporcionada por el usuario que pasa por la cadena de URL o consulta que busca un usuario

La diferencia fundamental es que un XSS reflejado normalmente dependerá de la interacción del usuario y solo afectará al usuario que abre el enlace con la carga maliciosa. Sin embargo, un XSS almacenado se puede ejecutar contra uno o más usuarios simplemente abriendo algunas páginas que muestran la carga útil.

Ubicación de la carga útil (DOM frente a no DOM)

La ubicación en la que se inyecta una carga útil determina si se clasifica la vulnerabilidad como una vulnerabilidad «DOM» o no. Esto hace referencia a la distinción entre el lugar donde se representa la carga útil:

  • XSS no DOM: La carga útil se representa en HTML, ya sea dentro de una etiqueta o un atributo
  • DOM XSS: La carga útil se representa dentro de JavaScript, como una <script>etiqueta ``, o un controlador de eventos como `onclick=""`

XSS - Primitivas de defensa

En esta sección, analizaremos los principios de los primitivos que subyacen a la defensa contra el XSS. Es esencial comprender los aspectos básicos de este tema, pero en la práctica, deberías confiar en tu biblioteca de plantillas para obtener el 99% de protección contra el XSS.

Al escribir plantillas que se representan para marcar o para ejecutar código en un navegador, la clave para protegerse contra el XSS es la *codificación*. Codificar, en este contexto, significa tomar una secuencia de caracteres y cambiarla a un formato que el intérprete procese de una manera específica.

Sin embargo, el tipo de codificación que se utilizará depende de la ubicación o el contexto en el que se utilizarán los datos.

  • Dentro de una etiqueta, como `Introduce <div>el usuario aquí</div>`: **Codificación HTML**
  • Dentro de un atributo, como `<input placeholder="User input here"></input>`: **Codificación de atributos**
  • Dentro de Javascript, como `<script>x = «Entrada de usuario aquí»;</script>`: **Codificación de Javascript

Algunos marcos renunciarán a la codificación como su principal medio de defensa y, en su lugar, utilizarán la desinfección para eliminar un valor de cualquier contenido que pueda ser peligroso. Este es un proceso mucho más complejo con muchos casos extremos que considerar. No se recomienda implementar sus propias rutinas de desinfección.

Echemos un vistazo a algunos ejemplos en varios idiomas para ver cómo se ve todo en acción.

C# - Inseguro: Razor

Si un objeto `IHTMLContent` tiene el prefijo `@`, el valor se coloca directamente en la plantilla sin ningún tipo de codificación.

<!--- UNSAFE: The htmlSnippet will get interpreted without any escaping --->
@Html .Raw (fragmento HTML)

C# - Seguro: Razor

De forma predeterminada, cualquier `cadena` con el prefijo `@` es HTML escapado en las plantillas de Razor.

<!--- SAFE: The htmlSnippet will get HTML escaped --->
@htmlSnippet

Java: seguro: JSP

Cuando se usa `c:out`, el XML escapa de forma predeterminada (que se puede cambiar con la propiedad `escapeXML), lo que protege contra el XSS en un contexto HTML, pero no en otros contextos.

<div><c:out value="<%= author %>" /></div>

Java: seguro: (fnxml)

De manera similar a lo anterior, también puedes llamar directamente a `fn:escapeXML, lo que hará que XML escape a la entrada que se le haya dado. Esto también protegerá solo en un contexto HTML.

<div>$ {fn:escapeXML (autor)}</div>

Javascript - Inseguro: Angular InnerHTML

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.

<!--- UNSAFE: The htmlSnippet will get interpreted without any encoding --->
<p [innerHTML] ="htmlSnippet"></p>

Javascript - Seguro: angular interpolado

La interpolación de texto de Angular mediante corchetes dobles (`{{` y `}}`) hará que el HTML escape de su salida, protegiéndolo contra el XSS.

<!--- SAFE: The htmlSnippet will get encoded and then interpreted --->
<p>{{HtmlSnippet}}</p>

Javascript - Inseguro: React DangerousInnerHTML

Al especificar la propiedad `dangerouslySetInnerHTML`, como su nombre indica, estará expuesto al riesgo de XSS debido a la desactivación de la codificación de salida.

<!--- UNSAFE: As the name suggests, the dangerouslySetInnerHTML attribute is dangerous as it does not escape the output --->
<div dangerouslySetInnerHTML= {{__html: htmlSnippet}} />;

Javascript - Seguro: React interpolado

La interpolación de texto por parte de React usando corchetes (`{` y `}`) hará que el HTML escape de su salida, protegiéndolo contra el XSS.

<!--- SAFE: The htmlSnippet will get encoded and then interpreted --->
<div>{Fragmento HTML}</div>

Python - Inseguro: Django

Si se usa el filtro `seguro` en una plantilla de Django, deshabilitará el escape automático de la salida y, por lo tanto, no protegerá contra el XSS.

<!--- UNSAFE: The htmlSnippet will not get HTML encoded --->
<div>{{HTMLSnippet | seguro}}</div>

Python - Seguro: Django

La interpolación de texto por parte de Django usando corchetes dobles (`{{` y `}}`) hará que el HTML escape de su salida, protegiéndolo contra el XSS.

<!--- SAFE: The htmlSnippet will HTML encoded --->
<div>{{nombre}}</div>