8

I am creating a web extension to help detecting postMessage activity in websites. Therefore, I want to detect it when a page attaches a message event listener, for example by calling this code:

window.addEventListener("message", ...)

Apparently it is not possible to get a list of event listeners. My next idea was to override addEventListener, so I can detect calls to it:

window.addEventListener = function(type) {
    if (type == "message") {
        // do something
    }
}

I have trouble injecting this code into the page:

  • A content script can access the DOM of each page, but not the window object. Changing the window.addEventListener on the content page has no effect on the actual page.
  • I can add a script element by modifying the DOM, but I have trouble getting the timing right. My script would need to run before any other script, and this method only works if there is already a DOM.
  • Functions like chrome.tabs.executeScript work on a specific tab, and I want to run code on every page. This differs if a page has iframes, where I also want to override addEventListener.

How can I override window.addEventListener globally from my extension? Or alternatively, is there another way to detect an event listener on message events?

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
  • 1
    See [Insert code into the page context using a content script](//stackoverflow.com/a/9517879) - you need to put the override code in a `script` element to run it in the page context. – wOxxOm Feb 15 '18 at 14:43
  • See also [chrome extension inject javascript at top of head before any other js](https://stackoverflow.com/questions/45247355/chrome-extension-inject-javascript-at-top-of-head-before-any-other-js) – Sjoerd Feb 15 '18 at 15:58
  • See also [How to disable facebook hotkeys with Chrome extension?](https://stackoverflow.com/questions/8982312/how-to-disable-facebook-hotkeys-with-chrome-extension) – Sjoerd Feb 15 '18 at 19:28

1 Answers1

6

To override a function, you need to run JavaScript before the page loads. You need to do the following:

  • In the manifest.json, specify that the content script is run before the document is loaded by setting run_at to document_start.
  • From the content script, inject static code into the page. Don't use an URL, but create a script tag that contains the code. I.e. script.textContent = actualCode and not script.src = url.
Sjoerd
  • 74,049
  • 16
  • 131
  • 175