7.8 KiB
Shadow DOM
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de segurança cibernética? Você quer ver sua empresa anunciada no HackTricks? ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e repositório hacktricks-cloud.
Informações Básicas
Shadow DOM faz parte do conjunto de recursos Web Components, que tem como objetivo permitir que desenvolvedores JS criem elementos personalizados reutilizáveis com sua funcionalidade encapsulada longe do restante do código do site.
Essencialmente, você pode usar o Shadow DOM para isolar o HTML e o CSS do seu componente do restante da página da 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 pai não penetrarão no shadow DOM.
// creating a shadow DOM
let $element = document.createElement("div");
$shadowDomRef = $element.attachShadow({ mode: "open" }); // open or closed
Normalmente, quando você anexa um shadow DOM "aberto" a um elemento, você pode obter uma referência ao shadow DOM com $element.shadowRoot
. No entanto, se o shadow DOM estiver anexado em modo "fechado", você não pode obter uma referência dessa maneira. Mesmo depois de ler toda a documentação do desenvolvedor que pude encontrar, ainda estou um pouco confuso sobre o propósito do modo fechado. De acordo com o Google:
Existe outra variação do shadow DOM chamada modo "fechado". Quando você cria uma árvore de sombra fechada, o JavaScript externo não poderá acessar o DOM interno do seu componente. Isso é semelhante ao funcionamento de elementos nativos como
<video>
. O JavaScript não pode acessar o shadow DOM de<video>
porque o navegador o implementa usando uma raiz de sombra em modo fechado.
No entanto, eles também afirmam:
As raízes de sombra fechadas não são muito úteis. Alguns desenvolvedores veem o modo fechado como um recurso de segurança artificial. Mas vamos ser claros, isso não é um recurso de segurança.
Acessando o Shadow DOM
window.find() e seleções de texto
A função window.find("texto_de_pesquisa")
penetra dentro de um shadow DOM. Essa função tem efetivamente a mesma funcionalidade que ctrl-F em uma página da web.
É possível chamar document.execCommand("SelectAll")
para expandir a seleção o máximo 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. Portanto, podemos exfiltrar o conteúdo do shadow DOM da seguinte maneira:
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 em que você pode obter uma injeção dentro de um shadow DOM onde não seria possível em uma página normal com crossorigin.
Um exemplo disso é se você tiver quaisquer elementos com o atributo contenteditable
. Este é um atributo HTML obsoleto e pouco utilizado que declara que o conteúdo desse elemento pode ser editado pelo usuário. Podemos usar seleções juntamente 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/style para uma injeção de HTML, adicionando a propriedade CSS a um elemento e, em seguida, utilizando o comando insertHTML
.
CTF
Verifique este writeup onde essa técnica foi usada como um desafio CTF: https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md
Referências
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Você trabalha em uma empresa de cibersegurança? Você quer ver sua empresa anunciada no HackTricks? Ou você quer ter acesso à última versão do PEASS ou baixar o HackTricks em PDF? Verifique os PLANOS DE ASSINATURA!
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Adquira o swag oficial do PEASS & HackTricks
- Junte-se ao 💬 grupo Discord ou ao grupo Telegram ou siga-me no Twitter 🐦@carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para o repositório hacktricks e para o repositório hacktricks-cloud.