HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

modifying globals, "window", "global" and other objects, in a restorable way

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
globalobjectswayglobalsmodifyingandwindowotherrestorable

Problem

Primary Concerns

-
As long as the stash is not within scope, globals such as
window/global would effectively be sanitized of any risky methods,
such as eval

-
The API feels complete, am I missing anything?

  • Are there any "risky" aspects to the sever method.



  • Any thoughts with regard to performance or security.



  • I don't think there is any performance implications from maintaining a stash of the extracted methods, as they would exist already, we are just moving them around.



  • is the layout below easy to read and understand, should I document these things in the future or should I just stick to the code?



Background Info

Scalpel (s5l) is a small class to shuffle properties
between objects.

Initially developed for some work being done within
the Electron framework, where "window" and "global"
needed to be pruned of insecure methods.

Scalpel will allow you to remove any methods from
these "global" type objects, and then restore them,
when/if you want.

Here is the condensed version:

```
class S5l / S{calpe}(5)l/ {
constructor (){ this.stash = {}; }

sever ( methods, contexts, message, stash ){
if(! Array.isArray(methods)) methods = [methods];
message = message ? message : ' has been disabled for security reasons.';
this.stash = stash ? stash : this.stash;
stash = this.stash;
methods.forEach(function(method){
contexts.forEach(function(tuple){
let label = Object.keys(tuple)[0];
if( Object.prototype.hasOwnProperty.call( tuple[label], method )){
stash[label] = stash[label] || {};
stash[label][method] = {
_f: tuple[label][method], // the function/method itself.
_r: tuple[label], // a parent reference, where the method was.
_m: method // the method/property name
};
tuple[label][method] = function(){ throw new Error( metho

Solution

I will just comment on the security aspect.
Let's say we want to disable window.eval:

let s = new S5l();
s.sever(['eval'], [{window: window}]);


Now, depending on your browser, you can still access eval either via

let frame = document.createElement('iframe');
document.body.appendChild(frame);
eval = frame.contentWindow.eval;


which might throw NS_ERROR_UNEXPECTED in Firefox but still works. In Chrome, one can alternatively restore overridden methods by accessing the DOMWindow prototype via

delete window.eval;
eval = window.constructor.prototype.eval;


Conclusion: There is probably no safe way to disable access to global attributes on the client side. Focus on preventing cross site scripting vulnerabilities etc. instead.

Code Snippets

let s = new S5l();
s.sever(['eval'], [{window: window}]);
let frame = document.createElement('iframe');
document.body.appendChild(frame);
eval = frame.contentWindow.eval;
delete window.eval;
eval = window.constructor.prototype.eval;

Context

StackExchange Code Review Q#159972, answer score: 3

Revisions (0)

No revisions yet.