Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you add a function to a hijacked JavaScript Array?

This question is related to What are the best practices to follow when declaring an array in Javascript?


Let's say a client, let's call them "D. B. Cooper", has a first requirement that the following code must run before any other JavaScript code:

Array = function(){
    alert('Mwahahahaha');
};

Furthermore, Cooper requires that custom functions must be added to the built in Array object (not the hijacked one). For example, if Array was unhijacked, this would be done with:

Array.prototype.coolCustomFunction = function(){
    alert('I have ' + this.length + ' elements!  Cool!');
};

Which would afford:

var myArray = [];
myArray.coolCustomFunction();

However, this is not compatible with the first requirement. Thus, how can you best fulfill both of D. B. Cooper's requirements?

Note: D.B. even wrote a test fiddle to help make sure solutions meet his requirements...what a guy!


Update: For those of you who like a challenge: please try to find an unhijackable cross-browser solution to this problem. For example, here's an even more hijacked test case (thanks for reformatting this Bergi) that hijacks Array, Object, Array.prototype.constructor, and Object.prototype.constructor. Thus far, it looks like there may be a browser-specific solution to this (see Bergi's comment on his answer, and let us know if you find a way to hijack it in FF), but it is unclear at this point if there is a cross-browser solution to this.

like image 509
Briguy37 Avatar asked Jul 17 '12 16:07

Briguy37


3 Answers

Whatever your Array function/constructor is, the literal syntax for arrays will always generate "real" arrays with their [[prototype]] set to the native array prototype object (once, this was a security vulnerability). So, you can always access that by using

Object.getPrototypeOf([])

even if Array or [].constructor are hijacked. (Will of course not work when Object is hijacked, then it get's really complicated)

(Brought D.B. down!)


If you want to use a workaround, in FF the following line will always work (and is not hijackable):

[].__proto__.coolCustomFunction = coolCustomFunction;
like image 89
Bergi Avatar answered Nov 10 '22 19:11

Bergi


Since Array is not necessarily equal to [].constructor, you could use [].constructor to refer to the original Array function since this is hardwired and Array = function(){} won't alter it.

Array = function () { alert("foo")};

// this will always point to the original Array
[].constructor.prototype.foo = "bar";

var myArray = [0, 1];
alert(myArray.foo) // alerts "bar"

http://jsfiddle.net/yXPJ8/5/

like image 29
Torsten Walter Avatar answered Nov 10 '22 18:11

Torsten Walter


Yes ... you just did ... but you created the array using [] .. if you use new Array() it works fine ...

See example here

like image 1
Manse Avatar answered Nov 10 '22 19:11

Manse