Secure Browser Runtime
This (blazing fast, 727B gzipped) library aims to provide a simple way to prevent the rewriting or overriding of several fundamental browser APIs that you need to work with on a daily basis, saving you from suffering unpleasant headaches while trying to debug something you didn't write, and happens to be done by an external source.
Installing
Using npm:
npm install secure-browser-runtime
Using yarn:
yarn add secure-browser-runtime
Using CDN:
Supported browsers
![]() IE / Edge |
![]() Firefox |
![]() Chrome |
![]() Safari |
![]() iOS Safari |
![]() Opera |
---|---|---|---|---|---|
IE10, IE11, Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
Usage
You can load the code through the import spec, it will be automatically executed.
;
Also, you can still use the require
function:
;
Important note: This must be placed at the very beginning of your application (e.g. main entrypoint for ES5+, first script in the DOM for pure HTML):
What happens when I load this in the browser?
With Great Power Comes Great Responsibility.
Have you ever stumbled upon code like this?
window;
Everything seems to be ok, huh?
Well, it actually may be a possibility that the above code will not behave as expected.
Imagine some third-party JS script included in your page that contains something like this:
window { // Do something very evil}
At this point, everything would depend on how the third-party script developed the new function which is assigned to that property.
To prevent this, we just wrap the properties we don't want to be overwritten,
by using the Object.defineProperty
method like this:
// We initially store the original reference into a constantconst propertyReference = windowaddEventListener;// Then we delete the reference to the previous value from the real objectdelete windowaddEventListener;// So that we can redefine it, setting the `writeable` option to falseObject;
Once this code is executed, every other attempt to overwrite that method will not work and the initial value will be kept instead.
Tip: this will likely help you too (just in case you're thinking to do stuff like this and break other people's functionalities) by throwing an error when trying to set values through the
=
operator or theObject.defineProperty()
method, and also when trying to use thedelete
keyword in Strict Mode.
Here's the full list of properties that will be enclosed in a non-writable version of their initial value:
Parent object | Property name | Parent object | Property name |
---|---|---|---|
window |
addEventListener |
document |
addEventListener |
window |
alert |
document |
adoptNode |
window |
atob |
document |
close |
window |
blur |
document |
createAttribute |
window |
btoa |
document |
createComment |
window |
clearInterval |
document |
createDocumentFragment |
window |
clearTimeout |
document |
createElement |
window |
close |
document |
createEvent |
window |
confirm |
document |
createTextNode |
window |
focus |
document |
execCommand |
window |
getComputedStyle |
document |
getElementById |
window |
getSelection |
document |
getElementsByClassName |
window |
matchMedia |
document |
getElementsByName |
window |
moveBy |
document |
getElementsByTagName |
window |
moveTo |
document |
hasFocus |
window |
open |
document |
importNode |
window |
print |
document |
normalize |
window |
prompt |
document |
normalizeDocument |
window |
removeEventListener |
document |
open |
window |
resizeBy |
document |
querySelector |
window |
resizeTo |
document |
querySelectorAll |
window |
scroll |
document |
removeEventListener |
window |
scrollBy |
document |
renameNode |
window |
scrollTo |
document |
write |
window |
setInterval |
document |
writeln |
window |
setTimeout |
||
window |
stop |
Contributing
Feel free to contribute adding elements to the list, if you think they should be protected, or maybe improve the structure and efficiency of the algorithm! Why not? Everything is welcome in the Open Source world :)