Ataque XSS utilizando etiquetas script, style e imagen

Aprende a infectar una página usando un ataque XSS con las etiquetas script, style o image. Mira cómo reemplazar el contenido de la página con el tuyo incluso sin JavaScript.

Daniel Gustaw

Daniel Gustaw

4 min read

Ataque XSS utilizando etiquetas script, style e imagen

Este artículo describe ejemplos de ataques XSS. El uso de etiquetas <script> es probablemente el caso más conocido, pero existen otras posibilidades. Puedes cambiar el contenido de un sitio web usando una etiqueta <img> o CSS puro.

Este es material educativo. ¡Recuerda que hackear sin autorización es ilegal! :)

Código del sitio web

Para presentar el ataque, creamos un sitio web simple basado en PHP. Aunque la mejor práctica es separar la lógica de la vista, por simplicidad y para minimizar el número de líneas de código las combinamos en un solo archivo: index.php. Para crear un sitio web vulnerable, este debe guardar la entrada del usuario y mostrarla en pantalla sin filtrarla.

Por simplicidad, prescindimos de una base de datos y utilizamos un archivo JSON. El primer archivo de nuestro proyecto es db.json:

db.json

["First comment","Second one"]

Para guardar los comentarios enviados a través del script PHP:

index.php

<?php
$comments = json_decode(file_get_contents('db.json'));

if($_SERVER["REQUEST_METHOD"] === "POST") {
    $comments[] = $_POST["comment"];
    file_put_contents('db.json', json_encode($comments));
}

Independientemente del método de solicitud, el script muestra el formulario y la lista de comentarios:

index.php

echo '<form action="" method="post">
    <input type="text" name="comment">
    <input type="submit" value="send">
</form>
<ul>';

foreach ($comments as $comment) {
    echo "<li>".$comment."</li>";
}
echo '</ul>';

Puedes iniciar el servidor local con el comando:

php -S localhost:8000

El sitio web creado se ve de la siguiente manera:

Es completamente funcional: permite agregar un comentario, guardarlo en JSON y mostrar la lista de comentarios. Si los usuarios solo quisieran agregar texto normal, aquí terminaría nuestra historia. Pero debemos asumir que al menos un usuario intentará atacar el sitio. :)

¿Cómo hackearlo?

Este flujo de datos (guardar en el servidor y mostrar en el cliente) permite un ataque XSS si el texto no se filtra adecuadamente. XSS (Cross-Site Scripting) permite a los atacantes inyectar scripts del lado del cliente en páginas web vistas por otros usuarios.

El código ejecutable inyectado es interpretado por el navegador, no por el servidor. Por lo tanto, no tomamos el control del servidor, pero sí podemos manipular el comportamiento del cliente. Los beneficios potenciales para el atacante incluyen:

El script puede estar almacenado en el servidor o incluirse en un enlace. En nuestro caso, queremos guardar el script en el archivo db.json enviándolo a través del formulario de comentarios. Queremos cambiar el contenido del sitio web a “Hacked by Daniel”. En cualquiera de los métodos presentados a continuación, el sitio web terminará viéndose así:

Script

La forma más sencilla es agregar una etiqueta <script> que cambie dinámicamente el contenido de la página tras cargarse:

<script>document.querySelector('html').innerHTML="Hacked By Daniel"</script>

Este código selecciona el elemento html raíz (toda la página) y reemplaza su contenido usando la propiedad innerHTML.

Estilo

Otro método funciona incluso si las etiquetas <script> se eliminan y JavaScript está deshabilitado en el navegador:

<style>html::before {content: "Hacked By Daniel";} body {display: none;}</style>

Definimos dos reglas CSS. La primera indica al navegador que añada el texto Hacked By Daniel antes del cuerpo del sitio web (body). La segunda oculta completamente el cuerpo de la página.

Imagen

Bloquear las etiquetas <script> y <style> en los comentarios no es suficiente, ya que también se pueden ejecutar scripts a través de controladores de eventos en otras etiquetas HTML:

<img src=undefined onerror='document.querySelector("html").innerHTML="Hacked By Daniel"'>

Este es un ejemplo de una imagen con una dirección inválida. Cuando la carga falla, el navegador ejecuta automáticamente el script dentro del atributo onerror.

¿Cómo defenderse?

Para defenderse de este ataque, debemos sanitizar los comentarios de los usuarios y escapar las etiquetas HTML. Podemos hacerlo modificando el código en index.php:

-      $comments[] = $_POST["comment"];
+      $comments[] = htmlspecialchars($_POST["comment"]);

Después de aplicar esta corrección, el texto ingresado en el formulario se mostrará literalmente como texto en la lista de comentarios, sin ser interpretado como etiqueta HTML:

Resumen

Mostramos ejemplos simples de ataques XSS utilizando diferentes etiquetas. Los frameworks modernos como Symfony o Laravel tienen mecanismos de seguridad integrados contra XSS, pero al escribir en PHP puro, siempre debes recordar usar funciones como htmlspecialchars.

Other articles

You can find interesting also.