6.9 KiB
Shadow DOM
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
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!
- Adquira o material oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção de NFTs exclusivos
- Junte-se ao grupo 💬 Discord ou ao grupo telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub HackTricks e HackTricks Cloud.
Informações Básicas
Shadow DOM é parte do conjunto de recursos 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.
// 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:
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 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, onde anchorElement
é uma referência a um elemento no shadow DOM. Assim, podemos exfiltrar conteúdos do shadow DOM da seguinte forma:
getSelection().anchorNode.parentNode.parentNode.parentNode.innerHTML
Mas isso não funciona no Chromium.
contenteditable ou injeção de CSS
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!
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
Referências
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
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!
- Adquira o merchandising oficial do PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção de NFTs exclusivos
- Junte-se ao grupo 💬 Discord ou ao grupo telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub HackTricks e HackTricks Cloud.