Dom Clobbering
Basics
Es posible generar variables globales dentro del contexto JS con los atributos id
y name
en las etiquetas HTML.
Solo ciertos elementos pueden usar el atributo name para clobber globals, son: embed
, form
, iframe
, image
, img
y object
.
Curiosamente, cuando usas un elemento form para clobber una variable, obtendrás el valor toString
del elemento en sí: [object HTMLFormElement]
pero con anchor el toString
será el href
del ancla. Por lo tanto, si clobber usando la etiqueta a
, puedes controlar el valor cuando se trata como una cadena:
Arrays & Attributes
También es posible sobrescribir un array y atributos de objetos:
Para sobrescribir un 3er atributo (por ejemplo, x.y.z), necesitas usar un form
:
Clobbering más atributos es más complicado pero aún posible, usando iframes:
La etiqueta de estilo se utiliza para dar suficiente tiempo al iframe para renderizarse. Sin ella, encontrarás una alerta de undefined.
Para sobrescribir atributos más profundos, puedes usar iframes con codificación html de esta manera:
Evasión de Filtros
Si un filtro está iterando a través de las propiedades de un nodo usando algo como document.getElementByID('x').attributes
, podrías sobrescribir el atributo .attributes
y romper el filtro. Otras propiedades del DOM como tagName
, nodeName
o parentNode
y más también son sobrescribibles.
Clobbering window.someObject
window.someObject
En JavaScript es común encontrar:
Manipular HTML en la página permite sobrescribir someObject
con un nodo DOM, lo que potencialmente introduce vulnerabilidades de seguridad. Por ejemplo, puedes reemplazar someObject
con un elemento de anclaje que apunte a un script malicioso:
En un código vulnerable como:
Este método explota la fuente del script para ejecutar código no deseado.
Truco: DOMPurify
te permite usar el cid:
protocolo, que no codifica en URL las comillas dobles. Esto significa que puedes inyectar una comilla doble codificada que será decodificada en tiempo de ejecución. Por lo tanto, inyectar algo como <a id=defaultAvatar><a id=defaultAvatar name=avatar href="cid:"onerror=alert(1)//">
hará que la HTML codificada "
sea decodificada en tiempo de ejecución y escape del valor del atributo para crear el evento onerror
.
Otra técnica utiliza un elemento form
. Ciertas bibliotecas del lado del cliente inspeccionan los atributos de un nuevo elemento de formulario creado para limpiarlos. Sin embargo, al agregar un input
con id=attributes
dentro del formulario, efectivamente sobrescribes la propiedad de atributos, impidiendo que el sanitizador acceda a los atributos reales.
Puedes encontrar un ejemplo de este tipo de clobbering en este CTF writeup.
Clobbering del objeto documento
Según la documentación, es posible sobrescribir atributos del objeto documento utilizando DOM Clobbering:
La interfaz Document soporta propiedades nombradas. Los nombres de propiedades soportados de un objeto Document en cualquier momento consisten en lo siguiente, en orden de árbol de acuerdo con el elemento que las contribuyó, ignorando duplicados posteriores, y con valores de atributos id que vienen antes de los valores de atributos de nombre cuando el mismo elemento contribuye ambos:
- El valor del atributo de contenido name para todos los elementos embed, form, iframe, img, y object que tienen un atributo de contenido name no vacío y están en un árbol de documento con documento como su raíz; - El valor del atributo de contenido id para todos los elementos object que tienen un atributo de contenido id no vacío y están en un árbol de documento con documento como su raíz; - El valor del atributo de contenido id para todos los elementos img que tienen tanto un atributo de contenido id no vacío como un atributo de contenido name no vacío, y están en un árbol de documento con documento como su raíz.
Usando esta técnica, puedes sobrescribir valores comúnmente utilizados como document.cookie
, document.body
, document.children
, e incluso métodos en la interfaz Document como document.querySelector
.
Escribir después del elemento clobbering
Los resultados de las llamadas a document.getElementById()
y document.querySelector()
pueden ser alterados al inyectar una etiqueta <html>
o <body>
con un atributo id idéntico. Así es como se puede hacer:
Además, al emplear estilos para ocultar estas etiquetas HTML/body inyectadas, se puede prevenir la interferencia de otro texto en el innerText
, mejorando así la eficacia del ataque:
Investigaciones sobre SVG revelaron que una etiqueta <body>
también puede ser utilizada de manera efectiva:
Para que la etiqueta HTML funcione dentro de SVG en navegadores como Chrome y Firefox, es necesaria una etiqueta <foreignobject>
:
Clobbering Forms
Es posible agregar nuevas entradas dentro de un formulario simplemente especificando el atributo form
dentro de algunas etiquetas. Puedes usar esto para agregar nuevos valores dentro de un formulario e incluso para agregar un botón nuevo para enviarlo (clickjacking o abusar de algún código JS .click()
):
Para más atributos de formulario en botón consulta esto.
Referencias
Heyes, Gareth. JavaScript para hackers: Aprende a pensar como un hacker.
Last updated