When using fetch to retrieve a payload containing a __proto__
, it seems that the Object prototype is not affected in the same way as when directly assigning to an object.
This behavior is beneficial as it ensures that the Object prototype remains unaffected by any API calls. However, I am curious about the mechanics behind this and why it happens?
For instance, considering a payload.json
file:
{
"__proto__": { "toString": "foobar" }
}
If we fetch this data:
fetch("payload.json")
.then(function(response) {
return response.json();
})
.then(function(json) {
console.log("--JSON from a fetch payload--");
console.log("payload.toString():", json.toString()); // [object Object]
console.log("json.__proto__:", json.__proto__); // {toString: "foobar"}
console.log("{}.toString()", {}.toString()); //[object Object]
console.log("--New object with __proto__ set--");
const x = { __proto__: { toString: () => "hacked" } };
console.log("x.toString(): ", x.toString());
console.log("{}.toString(): ", {}.toString());
console.log(
"JSON.parse('{}').toString(): ",
JSON.parse("{}").toString()
);
console.log("--Set proto with assignment--");
const y = {};
y.__proto__.toString = () => "polluted";
console.log("y.toString(): ", y.toString());
console.log("x.toString(): ", x.toString());
console.log("{}.toString(): ", {}.toString());
console.log(
"JSON.parse('{}').toString(): ",
JSON.parse("{}").toString()
);
});
The output will be:
--JSON from a fetch payload--
payload.toString(): [object Object]
json.__proto__:
Object {toString: "foobar"}
{}.toString() [object Object]
--New object with __proto__ set--
x.toString(): *** hacked ***
{}.toString(): [object Object]
JSON.parse('{}').toString(): [object Object]
--Set proto with assignment--
y.toString(): *** polluted ***
x.toString(): *** hacked ***
{}.toString(): *** polluted ***
JSON.parse('{}').toString(): *** polluted ***
I understand how the last example pollutes the object prototype, but I'm intrigued as to why json.__proto__
behaves differently when obtained through a fetch call.
You can view the above example on codesandbox.io