Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redefining the Array constructor in javascript

Tags:

javascript

Say I have the following code:

var secrets;
Array = function() {
  secrets = this;
};

The author of the above sample says that the code is redefining the Array constructor. First, I am not sure what the this refers to. Can anyone please advise?

Second: would the following code be equivalent?

var secrets;
function Array() {
  secrets = this;
}

By the way the above code is taken from the following article about a Json vulnerability: see here

like image 910
balteo Avatar asked Mar 13 '13 12:03

balteo


People also ask

What is JavaScript array constructor?

The JavaScript Array constructor property is used to return the constructor function for an array object. It only returns the reference of the function and not returns the name of the function. So, In JavaScript arrays, it returns the function Array() { [native code] }. Syntax: array.constructor.

What are the three ways to construct array in JavaScript?

This example shows three ways to create new array: first using array literal notation, then using the Array() constructor, and finally using String.prototype.split() to build the array from a string.

How do you change an array in JavaScript?

push() adds item(s) to the end of an array and changes the original array. unshift() adds an item(s) to the beginning of an array and changes the original array. splice() changes an array, by adding, removing and inserting elements.

How do you define an array called array1 in JavaScript?

Using an array literal is the easiest way to create a JavaScript Array. Syntax: const array_name = [item1, item2, ...]; It is a common practice to declare arrays with the const keyword.


2 Answers

In both examples you're defining the variable Array to be a function that assigns this to secrets. It just so happens that there already exists a global object called Array that other JS in the page might or might not use as a Constructor to make arrays. If you pop into your console and re-assign Array to be something else, you might start getting errors from code that explicitly depends on Array. However, arrays made literally with [] continue to work just fine, and in fact, their __proto__ still points to what was Array.prototype. So:

var arr1 = new Array('a','b','c');
// arr[0] -> 'a'

var arr2 = ['d','e','f'];
// arr[0] -> 'd'

var secrets;
Array = function() { secrets = this; };

var arr3 = new Array('g','h','i'); // nothing wrong here, because Array is a function
// arr3[0] -> undefined
// Array is just a function, you can't make arrays with new Array anymore
// and arr3 is just a function


var arr4 = ['j','k','l'];
// arr4[0] -> 'j'
// making array literals still works

as for this, nothing strange, still follows the rules of this. the fact that you're assigning a function to Array doesn't change how this behaves. so this points to the global object which in the browser is window unless you instantiate with new or use call or apply

the difference between both samples is the difference between a function expression and function declaration, see: What is the difference between a function expression vs declaration in Javascript?

like image 79
zertosh Avatar answered Sep 23 '22 10:09

zertosh


Yes, both snippets are equivalent. Both redefine the array constructor, in an attempt to intercept all array data used by the website where it's injected, as explained in the linked article. The value of this is supposed to be the newly constructed array.

This seems to have been allowed by ECMAScript 3, but disallowed by ECMAScript 5, now available on all modern browsers. So the exploit described in the article should no longer work.

like image 27
bfavaretto Avatar answered Sep 24 '22 10:09

bfavaretto