Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to prevent javascript within a shadow dom from accessing the DOM outside of it?

So if I have:

enter image description here

The js can change the text in component_test_div

Can I prevent that?

like image 826
user1146369 Avatar asked Sep 16 '25 12:09

user1146369


1 Answers

Script is not protected by shadow DOM

Shadow DOM only protects CSS leakage or interference with the content of the shadowRoot. It does not create a new namespace for JavaScript.

The code within shadow DOM is just code and has access to everything that is available to code that lives in a regular script file.

In this example I have some JS in the shadow root:

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'});
    let s = document.createElement('script');
    s.textContent = "function dog() { console.log('Bark, Bark'); }";
    this.shadowRoot.appendChild(s);
  }
}

customElements.define('my-el', MyEl);

setTimeout(()=>dog(), 2000);
<my-el></my-el>

After 2 seconds we call the function dog() and it works. That is because, even though this code is placed into a tag inside a shadowRoot, it still executes in the global scope.

The code OF a component is kept within the component's class and is bound by the rules of code in a class. Private members are not accessible from the outside.

Given that there is no way to segregate your JavaScript in a web component you need to remember that it is available to anyone within its scope.

If you place the code in an IIFE then you can prevent the outside from calling in. But there is still no way to keep the inside from calling out or manipulating things outside of the scope.


Alternate way to determine if your element is in shadowDOM

As an alternate to @Angel Politis's answer there is an easier way to determine if an element is in someone's shadowRoot:

function isInShadowDOM(el) {
  let ret = false;

  if (el.getRootNode) {
    doc = el.getRootNode();
    ret = (doc !== document);
  }

  return ret;
}
like image 77
Intervalia Avatar answered Sep 18 '25 10:09

Intervalia