SpaceChuppy
SpaceChuppy

Reputation: 23

Why does node js behave like this?

Consider the following code

function getCleanObject() {
    var obj = {};
    for (var _i = 0, _a = Object.getOwnPropertyNames(obj.__proto__); _i < _a.length; _i++) {
        var prop = _a[_i];
        obj[prop] = undefined;
    }
    obj.__proto__ = undefined;
    return obj;
}
var a = 1;
console.log(getCleanObject(a).__proto__);
//'undefined' in browser
//'{}' in nodejs

A simple function which returns object and everything is stripped off or set to undefined. When this is executed in a browser console, we get undefined which is expected because __proto__ is set to undefined, but when we execute the same code in node, we get {}, I'm confused why this happens.

This was part of picoCTF lambdash 3 CTF competition

Upvotes: 2

Views: 125

Answers (1)

Estus Flask
Estus Flask

Reputation: 222369

getCleanObject doesn't make much sense because it assigns properties and then tries to unset object prototype, this will result in an object with a lot of garbage keys.

__proto__ is non-compliant property that may exist in some implementations but shouldn't be relied on. Proper ways to access object prototype are Object.getPrototypeOf and Object.setPrototypeOf.

__proto__ will work in V8 (Node.js, Chrome) because they support it. It is a descriptor on Object.prototype:

({}).hasOwnProperty('__proto__') === false
(Object.prototype).hasOwnProperty('__proto__') === true

It doesn't allow arbitrary values to be assigned to it, only null and objects:

The proto property of Object.prototype is an accessor property (a getter function and a setter function) that exposes the internal [[Prototype]] (either an object or null) of the object through which it is accessed.

obj.__proto__ = undefined is incorrect and shouldn't be expected to work. It may work in Node as obj.__proto__ = null. And the correct way is Object.setPrototypeOf(obj, null).

If there's no existing object that should be modified (modifying prototypes is discouraged because this can kill optimizations) as in getCleanObject then it could be:

const obj = Object.create(null);

Upvotes: 5

Related Questions