1.1.1 • Published 6 years ago

secure-browser-runtime v1.1.1

Weekly downloads
3
License
ISC
Repository
github
Last release
6 years ago

Secure Browser Runtime

npm version Build Status

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:

<script src="https://unpkg.com/secure-browser-runtime/dist/main.js"></script>

Supported browsers

IE / EdgeFirefoxChromeSafariiOS SafariOpera
IE10, IE11, Edgelast 2 versionslast 2 versionslast 2 versionslast 2 versionslast 2 versions

Usage

You can load the code through the import spec, it will be automatically executed.

import 'secure-browser-runtime';

Also, you can still use the require function:

require('secure-browser-runtime');

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.addEventListener('load', function(e) {
  console.log('Document is ready!');
  // Do some magic...
});

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.addEventListener = function(eventName, callback, ...others) {
  // 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 constant
const propertyReference = window.addEventListener;
// Then we delete the reference to the previous value from the real object
delete window.addEventListener;
// So that we can redefine it, setting the `writeable` option to false
Object.defineProperty(window, 'addEventListener', {
  value: propertyReference,
  writeable: false,
});

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 the Object.defineProperty() method, and also when trying to use the delete 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 objectProperty nameParent objectProperty name
windowaddEventListenerdocumentaddEventListener
windowalertdocumentadoptNode
windowatobdocumentclose
windowblurdocumentcreateAttribute
windowbtoadocumentcreateComment
windowclearIntervaldocumentcreateDocumentFragment
windowclearTimeoutdocumentcreateElement
windowclosedocumentcreateEvent
windowconfirmdocumentcreateTextNode
windowfocusdocumentexecCommand
windowgetComputedStyledocumentgetElementById
windowgetSelectiondocumentgetElementsByClassName
windowmatchMediadocumentgetElementsByName
windowmoveBydocumentgetElementsByTagName
windowmoveTodocumenthasFocus
windowopendocumentimportNode
windowprintdocumentnormalize
windowpromptdocumentnormalizeDocument
windowremoveEventListenerdocumentopen
windowresizeBydocumentquerySelector
windowresizeTodocumentquerySelectorAll
windowscrolldocumentremoveEventListener
windowscrollBydocumentrenameNode
windowscrollTodocumentwrite
windowsetIntervaldocumentwriteln
windowsetTimeout
windowstop

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 :)