Dom Clobbering
Conceptos básicos
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 de formulario para clobber una variable, obtendrás el valor de toString
del propio elemento: [object HTMLFormElement]
pero con el ancla el toString
será el href
del ancla. Por lo tanto, si clobberizas 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 un objeto:
Para sobrescribir un tercer atributo (por ejemplo, x.y.z), necesitas usar un form
:
Sobrescribir más atributos es más complicado pero aún posible, utilizando iframes:
La etiqueta de estilo se utiliza para dar suficiente tiempo al iframe para renderizar. Sin ella, verás una alerta de indefinido.
Para sobrescribir atributos más profundos, puedes usar iframes con codificación html de esta manera:
Burlando Filtros
Si un filtro está recorriendo las propiedades de un nodo usando algo como document.getElementByID('x').attributes
, podrías sobrescribir la propiedad .attributes
y romper el filtro. Otras propiedades del DOM como tagName
, nodeName
o parentNode
y más también son sobrescribibles.
Sobrescribiendo window.someObject
window.someObject
En JavaScript es común encontrar:
Manipular HTML en la página permite sobrescribir someObject
con un nodo DOM, potencialmente introduciendo vulnerabilidades de seguridad. Por ejemplo, puedes reemplazar someObject
con un elemento de anclaje apuntando 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 protocolo cid:
, que no codifica en URL las comillas dobles. Esto significa que puedes inyectar una comilla doble codificada que se decodificará 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 comilla HTML codificada "
sea decodificada en tiempo de ejecución y escapará del valor del atributo para crear el evento onerror
.
Otra técnica utiliza un elemento form
. Algunas bibliotecas del lado del cliente inspeccionan los atributos de un elemento de formulario recién creado para limpiarlos. Sin embargo, al agregar un input
con id=attributes
dentro del formulario, sobrescribes efectivamente la propiedad de atributos, evitando que el sanitizador acceda a los atributos reales.
Puedes encontrar un ejemplo de este tipo de clobbering en este informe de CTF.
Sobrescribiendo el objeto documento
Según la documentación, es posible sobrescribir atributos del objeto documento utilizando el DOM Clobbering:
La interfaz Document admite propiedades con nombre. Los nombres de propiedad admitidos de un objeto Document document en cualquier momento consisten en lo siguiente, en orden de árbol según el elemento que los contribuyó, ignorando duplicados posteriores, y con valores de atributos id que vienen antes de valores de atributos de nombre cuando el mismo elemento contribuye ambos:
- El valor del atributo de contenido de nombre para todos los elementos expuestos embed, form, iframe, img y elementos expuestos object que tienen un atributo de contenido de nombre no vacío y están en un árbol de documentos con el documento como su raíz; - El valor del atributo de contenido id para todos los elementos expuestos object que tienen un atributo de contenido id no vacío y están en un árbol de documentos con el 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 de nombre no vacío, y están en un árbol de documentos con el documento como su raíz.
Utilizando 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
.
Escribiendo después del elemento clobbered
Los resultados de las llamadas a document.getElementById()
y document.querySelector()
pueden ser alterados al inyectar una etiqueta <html>
o <body>
con un atributo de id idéntico. Así es como se puede hacer:
Además, al emplear estilos para ocultar estas etiquetas HTML/body inyectadas, se puede evitar la interferencia de otros textos 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 necesario usar la etiqueta <foreignobject>
:
Sobrescribiendo Formularios
Es posible agregar nuevas entradas dentro de un formulario simplemente especificando el atributo form
dentro de algunas etiquetas. Puedes usar esto para añadir nuevos valores dentro de un formulario e incluso agregar un nuevo botón para enviarlo (clickjacking o abusando de algún código JS .click()
):
Para obtener más atributos de formulario en botón, consulte esto.
Referencias
Heyes, Gareth. JavaScript para hackers: Aprende a pensar como un hacker.
Última actualización