Reputation: 23
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
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