hacktricks/pentesting-web/xss-cross-site-scripting/shadow-dom.md

83 lines
6.9 KiB
Markdown

# Shadow DOM
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF**, confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
## Informações Básicas
Shadow DOM é parte do conjunto de recursos [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web\_Components), que visa permitir que desenvolvedores JS criem elementos personalizados reutilizáveis com sua funcionalidade encapsulada, separada do restante do código do site.
Essencialmente, você pode usar o Shadow DOM para **isolar o HTML e CSS do seu componente do restante da página web**. Por exemplo, se você criar IDs de elementos em um shadow DOM, eles **não entrarão em conflito com IDs de elementos no DOM pai**. Quaisquer seletores CSS que você utilizar no seu shadow DOM serão aplicados apenas dentro do shadow DOM e não ao DOM pai, e quaisquer seletores que você utilizar no DOM pai não penetrarão dentro do shadow DOM.
```js
// creating a shadow DOM
let $element = document.createElement("div");
$shadowDomRef = $element.attachShadow({ mode: "open" }); // open or closed
```
Normalmente, quando você anexa um **"open" shadow DOM a um elemento**, você pode obter uma referência ao shadow DOM com **`$element.shadowRoot`**. No entanto, se o shadow DOM for anexado em modo **"closed"**, você **não pode obter uma referência** a ele dessa maneira. Mesmo após ler toda a documentação para desenvolvedores que pude encontrar, ainda estou um pouco incerto sobre o propósito do modo fechado. [De acordo com o Google](https://developers.google.com/web/fundamentals/web-components/shadowdom):
> Existe outra variação de shadow DOM chamada modo "closed". Quando você cria uma árvore shadow **closed**, **o JavaScript externo não será capaz de acessar o DOM interno do seu componente**. Isso é semelhante a como elementos nativos como `<video>` funcionam. O JavaScript não pode acessar o shadow DOM de `<video>` porque o navegador o implementa usando uma raiz de shadow em modo fechado.
No entanto, eles também afirmam:
> Raízes de shadow em modo fechado não são muito úteis. Alguns desenvolvedores verão o modo fechado como um **recurso de segurança artificial**. Mas vamos deixar claro, **não** é um recurso de segurança.
## Acessando o Shadow DOM
### window.find() e seleções de texto <a href="#introducing-windowfind-and-text-selections" id="introducing-windowfind-and-text-selections"></a>
A função **`window.find("search_text")` penetra dentro de um shadow DOM**. Essa função efetivamente tem a mesma funcionalidade que ctrl-F em uma página da web.
É possível chamar **`document.execCommand("SelectAll")`** para expandir a seleção tanto quanto possível e, em seguida, chamar **`window.getSelection()`** para **retornar o conteúdo** do texto selecionado dentro do shadow DOM.
No **firefox**, você pode usar `getSelection()`, que retorna um objeto [Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection), onde `anchorElement` é uma **referência a um elemento no shadow DOM**. Assim, podemos exfiltrar conteúdos do shadow DOM da seguinte forma:
```js
getSelection().anchorNode.parentNode.parentNode.parentNode.innerHTML
```
Mas isso não funciona no Chromium.
### contenteditable ou injeção de CSS <a href="#contenteditable-or-css-injection" id="contenteditable-or-css-injection"></a>
Uma maneira pela qual podemos interagir com o shadow DOM é se tivermos uma **injeção de HTML ou JS dentro dele**. Existem algumas situações interessantes onde você pode obter injeção dentro de um shadow DOM onde não seria possível em uma página normal com crossorigin.
Um exemplo é se você tem algum **elemento com o atributo `contenteditable`**. Este é um atributo HTML obsoleto e pouco usado que declara o **conteúdo daquele elemento como editável pelo usuário**. Podemos usar seleções junto com a API **`document.execCommand`** para interagir com um elemento contenteditable e obter uma injeção de HTML!
```js
find('selection within contenteditable');
document.execCommand('insertHTML',false,'<svg/onload=console.log(this.parentElement.outerHTML)>')
```
Talvez ainda mais interessante, **`contenteditable`** pode ser declarado em qualquer elemento no chromium aplicando uma **propriedade CSS obsoleta: `-webkit-user-modify:read-write`**
Isso nos permite **elevar uma injeção de CSS/estilo para uma injeção de HTML**, adicionando a propriedade CSS a um elemento e, em seguida, utilizando o comando `insertHTML`.
## CTF
Confira este writeup onde essa técnica foi usada como um desafio de CTF: [https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md](https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md)
## Referências
* [https://blog.ankursundara.com/shadow-dom/](https://blog.ankursundara.com/shadow-dom/)
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
Outras formas de apoiar o HackTricks:
* Se você quer ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)!
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>