Как удалить свойство __proto__ из объекта JSON?
У меня есть следующая функция, основанная на 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);
})
Ниже приведен код на стороне клиента, который делает запросы AJAX:
//function on client side making an ajax request
$.get("/loginCheck",function(data,status){
console.log(data);
});
В первом коде на стороне сервера, req.user
это объект mongodb, созданный mongoose. Что я хочу сделать, это отправить объект данных (который имеет некоторые выбранные атрибуты req.user
объект) и отправить объект как JSON в качестве ответа.
Переменная x
пользовательская переменная
Проблема: когда я отправляю data
возразить клиенту, __proto__
атрибут также добавляется с объектом, который не происходит при отправке x
клиенту. Но я не хочу __proto__
на стороне клиента, потому что из некоторых статей я обнаружил, что есть проблемы с безопасностью __proto__
,
Мне нужна помощь как убрать __proto__
от data
объект.
4 ответа
Вам не нужно удалять это. Это не вызывает никаких проблем / проблем.
Вы можете использовать как это.
$.each(data, function(k, v) {
console.log(k, v);
});
Вы можете отказаться от прототипа объекта, просто используя Object.create(null)
и определение свойств, которые вы хотите использовать.
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
И при таком подходе вам больше не нужно проверять наличие obj.hasOwnProperty(key)
for (var key in obj) {
// do something
}
Читать далее: True Hash Maps в 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)
Отправка __proto__
выход с сервера может создать объект JSON, который может сломать вещи, если ключи передаются другому объекту без удаления __proto__
или утечка конфиденциальных данных.
Необычно то, что он появляется в закодированном JSON, поскольку обычно его игнорируют. Это говорит о том, что проблема может быть в другом месте. Возможно, из-за того, что вы используете библиотеку, утечка происходит случайно или используется. Его можно использовать в закрытой системе, но нельзя допускать его ни в систему, ни из нее.
// If is optional.
if('__proto__' in obj)
// This may cause unintended consequences.
delete(obj.__proto__);
При получении данных вы также должны быть очень осторожны, чтобы они не содержали __proto__
свойство. Это может привести к сбою или компрометации сервера, если этот ключ будет скопирован на другой объект.
При создании собственного объекта есть уловки для изменения его поведения, такие как использование defineProperty, но эти уловки, как правило, не устраняют проблему полностью.