I am creating a chrome extension for blocking ads. Everything worked pretty fine so far. My goal is to:
- Disable
WebSocket
- Disable
console.log
- Disable
alert
- Disable popups (
window.open
) - Disable
onbeforeunload
Of course, it is supposed to block these functions only on specified websites. I searched on how to block a function. What I found is that the only way to disable a function using extension is to
- In
manifest.json
add a content scriptinit.js
which will run atdocument_start
(this will prevent any other code from being executed before my extension's code, so nobody can steal and save reference to these functions before I disable them) - From
init.js
inject code in webpage, so that my extension can access non-sandboxed environment - Override blacklisted functions
I did everything, but the problem was how to override functions. I found on EcmaScript7 specification that there is no way to detect if a function is proxy instance or not. So, I proxyfied every of these functions and it works as expected. Websites couldn't notice that I've overriden all of these functions.
However, it works for all functions expect addEventListener
. In order to block onbeforeunload
, I should add a proxy handler to it and track calls to check if listener name is onbeforeunload
. I wrote the following script:
addEventListener = new Proxy(addEventListener, {
apply: (f, t, args) => {
if(args[0] !== 'onbeforeunload'){
f.apply(t, args);
}
}
});
This should filter calls and allow only calls which doesn't set onbeforeunload
event. However, it throws ReferenceError: addEventListener is not defined. It surprised me a lot. I supposed that it is maybe because addEventListener
is not yet initialized at document_start
, but console.log(typeof addEventListener) logs function
to console. How is that even possible?
I couldn't explain it. However, I tried to put it in a function and then to requestAnimationFrame
to that function until addEventListener
become accessible (I ecapsulated the above code in try...catch
too). But, it turns out that modifying addEventListener
always throws ReferenceError, while just accessing it never throws error.
I also tried to access it from developer console and from javascript:...
method, but it behaves normally, I can modify it without any errors.
Edit
For sure, the problem isn't like this one, becuase I properly injected script into non-sandboxed (real) page environment and I have access to real window
object.