I have the following function based on Node-Express:
//function on server side
app.get('/loginCheck', loggedCheck, function(req, res) {
var data = {local: {}, facebook: {}};
data.id = req.user._id;
data.local.email = req.user.local.email;
data.local.fname = req.user.local.fname;
data.local.lname = req.user.local.lname ;
data.local.college = req.user.local.college ;
data.local.degree = req.user.local.degree ;
data.year = req.user.year ;
data.mobile = req.user.mobile ;
data.city = req.user.city ;
data.facebook.id = req.user.facebook.id ;
//res.json(data);
var x = {};
x.name = "someName"
res.json(x);
})
Following is the code on client side which makes an ajax requests:
//function on client side making an ajax request
$.get("/loginCheck",function(data,status){
console.log(data);
});
In the former code on server side, req.user
is a mongodb object created by mongoose. What I want to do is send the data object (which has some selected attributes of req.user
object) and send the object as JSON as response.
The variable x
is a custom created variable.
The problem is:
When I send the data
object to client, __proto__
attribute is also added with the object which is not happening when I am sending x
to the client.
But, I don't want the __proto__
in the client side, because, from some articles, I found that there are security issues with __proto__
.
I need help on how to remove __proto__
from the data
object.
I have the following function based on Node-Express:
//function on server side
app.get('/loginCheck', loggedCheck, function(req, res) {
var data = {local: {}, facebook: {}};
data.id = req.user._id;
data.local.email = req.user.local.email;
data.local.fname = req.user.local.fname;
data.local.lname = req.user.local.lname ;
data.local.college = req.user.local.college ;
data.local.degree = req.user.local.degree ;
data.year = req.user.year ;
data.mobile = req.user.mobile ;
data.city = req.user.city ;
data.facebook.id = req.user.facebook.id ;
//res.json(data);
var x = {};
x.name = "someName"
res.json(x);
})
Following is the code on client side which makes an ajax requests:
//function on client side making an ajax request
$.get("/loginCheck",function(data,status){
console.log(data);
});
In the former code on server side, req.user
is a mongodb object created by mongoose. What I want to do is send the data object (which has some selected attributes of req.user
object) and send the object as JSON as response.
The variable x
is a custom created variable.
The problem is:
When I send the data
object to client, __proto__
attribute is also added with the object which is not happening when I am sending x
to the client.
But, I don't want the __proto__
in the client side, because, from some articles, I found that there are security issues with __proto__
.
I need help on how to remove __proto__
from the data
object.
-
You cannot remove
__proto__
, an internal property. – Bhojendra Rauniyar Commented Jan 12, 2015 at 11:58 -
2
@BhojendraSah:
.__proto__
is not an internal property, but one inherited fromObject.prototype
– Bergi Commented Jan 12, 2015 at 13:55 - 1 Security issues? No, you must have misread that. Can you point us to those articles? – Bergi Commented Jan 12, 2015 at 13:57
-
2
res.json
will not include the__proto__
property. Are you sure you're seeing it in the actual HTTP response? – JohnnyHK Commented Jan 12, 2015 at 14:30
4 Answers
Reset to default 5You can forego a prototype on an object simply by using Object.create(null)
and defining the properties you wish to use.
var obj = Object.create(null);
Object.defineProperty(obj, {
'foo': {
value: 1,
enumerable: true,
},
'bar': {
value: 2,
enumerable: false
}
});
// or...
obj.foo = 1
obj.bar = 2
/* various checks */
obj instanceof Object; // false
Object.prototype.isPrototypeOf(obj); // false
Object.getPrototypeOf(obj); // null
obj + ""; // TypeError: Cannot convert object to primitive value
'toString' in obj; // false
foo; // 1
obj['bar']; // 2
JSON.stringify(obj); // {"foo":1}
{}.hasOwnProperty.call(obj, 'foo'); // true
{}.propertyIsEnumerable.call(obj, 'bar'); // false
And in this approach, you no longer need to check for obj.hasOwnProperty(key)
for (var key in obj) {
// do something
}
Read More: True Hash Maps in JavaScript
MDN: Object.defineProperty() & Object.create()
// with __proto__
var obj = {} // equivalent to Object.create(Object.prototype);
obj.key = 'value'
console.log(obj)
// without __proto__
var bareObj = Object.create(null)
Object.defineProperty(bareObj, {
'key': {
value: 'value',
enumerable: false,
configurable: true,
writable: true
}
})
// or... bareObj.key = 'value'
console.log(bareObj)
You don't need to remove that. It doesn't cause any trouble/problem.
You can use like this.
$.each(data, function(k, v) {
console.log(k, v);
});
Sending __proto__
out from the server can create a JSON object that may break things if the keys are transferred to another object without removing __proto__
or leak sensitive data.
It's unusual that it would appear in encoded JSON as it is usually ignored. That suggests there might be a problem or kludge elsewhere. It's possible the library you're using it leaking it by accident or making use of it. It may be alright to make use of it in a closed system but it should not be allowed either into or out of the system.
// If is optional.
if('__proto__' in obj)
// This may cause unintended consequences.
delete(obj.__proto__);
On receiving data you should also be very careful that it doesn't contain a __proto__
property. This can crash or promise the server if that key is copied over to another object.
If creating your own object there are tricks to change it's behaviour such as using defineProperty but these tricks tend not to eliminate the problem entirely.
Just write
String(<put here your data>)