79137783

Date: 2024-10-29 15:04:25
Score: 0.5
Natty:
Report link

The suggested fix does not work if the script attaching the shadow root is inline in the page.

For example:

<script>
const shadowHost = document.getElementById('shadow-host');
const shadowRoot = shadowHost.attachShadow({ mode: 'closed' });
...
</script>

the reason is that the script element created in e.g., shadowInject.js in BlackHole's answer, requires the browser to fetch the script and that is done asynchronously, while the script inline in the page is executed immediately as the page loads and therefore the script overrides Element.prototype.attachShadow after it's already been called.

If anyone can think of a solution, here are some of the things I tried and did not work or were not viable solutions for other reasons:

  1. inject an inline script instead of a script with src attribute e.g.,
let script = document.createElement('script');
script.innerText = '...hook attachShadow...';
(document.head||document.documentElement).append(script);

this is not a viable solution because it requires unsafe-inline to the CSP and that is the worst possible thing.

  1. inject a preload for the script before injecting the script element - this doesn't help either and the inline script in the page still calls Element.attachShadow before it is hooked.

It baffles me that in 2024 extensions do not have easy and streamlined access to content inside shadow roots (while devtools does!) and need to resort to this kind of hack. If anyone can think of a way to either gaining access to the DOM content of a shadow root from a chrome extension AFTER it's been created OR alternatively, to ensure Element.attachShadow is hooked before any script can invoke it.... I will be endlessly grateful :)

Reasons:
  • Blacklisted phrase (1): did not work
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Uriel G