DOM XSS in jQuery selector sink using a hashchange event – PortSwigger Write Up

En este post vamos a estar resolviendo el laboratorio: “DOM XSS in jQuery selector sink using a hashchange event”:


Para resolver el laboratorio, tenemos que enviar a una víctima un exploit que aproveche la vulnerabilidad del laboratorio para ejecutar la función print().

Lo primero de todo es acceder al laboratorio:


En este caso, no vemos ninguna barra de búsqueda o página de feedback como ha ocurrido en otros retos de XSS. Sin embargo, si nos vamos al código fuente, nos encontramos con el siguiente trozo de código:


Este código, básicamente lo que hace es que cuando se especifica en la URL algo después de un hashtag, busca este valor en la web y hace un scroll hasta la coincidencia.

Por ejemplo, si nos vamos abajo del todo del laboratorio, podemos ver como hay un post que tiene la palabra “Resume” en el título:


Sabiendo esto, vamos a buscar por:

❯ <URL>/#Resume


Damos enter.


Y aunque en la imagen no se pueda apreciar, nos redirige automáticamente hacia el post que contiene la palabra.

Para ver como explotar esto, vamos a traer el código de nuevo:


Como podemos observar, realmente lo que ocurre en el código, es que cuando especificamos algo después del hashtag, jQuery intenta busca un elemento h2 que contenga lo que hemos dicho. Cuando encuentra el elemento, este se almacena en la variable post, por lo que ahora, lo que contiene es un elemento de jQuery que se ve de la siguiente forma:


Posteriormente, si la variable post tiene algun dato almacenado, se obtiene el primer elemento del objeto jQuery y se usa el método scrollIntoView().

Aqui la vulnerabilidad como tal, se encuentra en la primera linea, en el selector sink de jQuery ($()):



Si no se sanitiza bien, lo que ocurre en aproximadamente en el código es lo siguiente:

  • $(‘section.blog-list h2:contains(‘ + decodeURIComponent(window.location.hash.slice(1)) + ‘)’);
  • $(‘section.blog-list h2:contains(‘ + Hola + ‘)’);

Por lo tanto, si ponemos un payload como el siguiente:

❯ <img src=/ onerror=print()>

Mas o menos, ocurriría algo así:

  • $(‘section.blog-list h2:contains(‘ + <img src=/ onerror=print()> + ‘)’);

De esta forma, se interpretaría. Vamos a probarlo:


Damos enter:


Y efectivamente se ejecuta. Ahora tenemos que crear un exploit que mandemos a la víctima y se haga uso de esta vulnerabilidad. Para ello nos vamos al servidor del exploit:



En este caso, la idea es automatizar la explotación usando un simple <iframe>:


Antes de enviarlo vamos a ver como se vería:



La victima al visitar una web con nuestro código, vería lo que estamos viendo, un pequeño iframe de la web, e inmediatamente después de que cargase la web, se ejecutaría la función print():


Por lo que, viendo que funciona. Simplemente lo guardamos y lo enviamos a la víctima:



De esta forma, conseguimos resolver el laboratorio:



¡Un saludo y espero que os sirva de apoyo!