6.5 KiB
Shadow DOM
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Basic Information
Shadow DOM is part of the Web Components feature suite, which aims to allow JS developers to create reusable custom elements with their functionality encapsulated away from the rest of the website code.
Essentially, you can use the Shadow DOM to isolate your component's HTML and CSS from the rest of the webpage. For example, if you create element IDs in a shadow DOM, they will not conflict with element IDs in the parent DOM. Any CSS selectors you utilize in your shadow DOM will only apply within the shadow DOM and not to the parent DOM, and any selectors you utilize in the parent will not penetrate within the shadow DOM.
// creating a shadow DOM
let $element = document.createElement("div");
$shadowDomRef = $element.attachShadow({ mode: "open" }); // open or closed
Normally, when you attach an "open" shadow DOM to an element, you can obtain a reference to the shadow DOM with $element.shadowRoot
. However, if the shadow DOM is attached under "closed" mode, you can't obtain a reference to it this way. Even after reading all developer documentation I could find, I'm still slightly unclear about the purpose of closed mode. According to Google:
There's another flavour of shadow DOM called "closed" mode. When you create a closed shadow tree, outside JavaScript won't be able to access the internal DOM of your component. This is similar to how native elements like
<video>
work. JavaScript cannot access the shadow DOM of<video>
because the browser implements it using a closed-mode shadow root.
However, they also state:
Closed shadow roots are not very useful. Some developers will see closed mode as an artificial security feature. But let's be clear, it's not a security feature.
Accessing the Shadow DOM
window.find() and text selections
The function window.find("search_text")
penetrates within a shadow DOM. This function effectively has the same functionality as ctrl-F on a webpage.
It's possible to call document.execCommand("SelectAll")
to expand the selection as much as possible and then call window.getSelection()
to return the contents of selected text inside the shadow DOM.
In firefox you can use getSelection()
which returns a Selection object, where anchorElement
is a reference to an element in the shadow DOM. So, we can exfiltrate contents of the shadow DOM as follows:
getSelection().anchorNode.parentNode.parentNode.parentNode.innerHTML
But this doesn't work in Chromium.
contenteditable or CSS injection
One way we might be able to interact with the shadow DOM is if we have an HTML or JS injection inside of it. There are some interesting situations where you can obtain injection within a shadow DOM where you wouldn't be able to on a normal crossorigin page.
One example, is if you have any elements with the contenteditable
attribute. This is a deprecated and little used HTML attribute that declares the content of that element to be user-editable. We can use selections along with the document.execCommand
API to interact with a contenteditable element and obtain an HTML injection!
find('selection within contenteditable');
document.execCommand('insertHTML',false,'<svg/onload=console.log(this.parentElement.outerHTML)>')
Perhaps even more interestingly, contenteditable
can be declared on any element in chromium by applying a deprecated CSS property: -webkit-user-modify:read-write
This allows us to elevate a CSS/style injection into an HTML injection, by adding the CSS property to an element, and then utilizing the insertHTML
command.
CTF
Check this writeup where this technique was used as a CTF challenge: https://github.com/Super-Guesser/ctf/blob/master/2022/dicectf/shadow.md
References
Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!
Other ways to support HackTricks:
- If you want to see your company advertised in HackTricks or download HackTricks in PDF Check the SUBSCRIPTION PLANS!
- Get the official PEASS & HackTricks swag
- Discover The PEASS Family, our collection of exclusive NFTs
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦 @carlospolopm.
- Share your hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.