如何从JSON对象中删除__proto__属性?

时间:2015-01-12 11:57:34

标签: javascript json node.js mongodb mongoose

我有以下基于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是由mongoose创建的mongodb对象。我想要做的是发送数据对象(具有req.user对象的一些选定属性)并将对象作为JSON发送为响应。

变量x是自定义创建的变量。

问题是: 当我将data对象发送到客户端时,__proto__属性也会添加到我向客户端发送x时未发生的对象。 但是,我不希望客户端__proto__,因为从某些文章中我发现__proto__存在安全问题。

我需要有关如何从__proto__对象中删除data的帮助。

4 个答案:

答案 0 :(得分:3)

只需使用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 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)

答案 1 :(得分:1)

您不需要删除它。它不会造成任何麻烦/问题。

你可以这样使用。

public String downloadUrl(String strUrl) throws IOException {
    String data = "";
    InputStream iStream = null;
    HttpURLConnection urlConnection = null;
    try{
        URL url = new URL(strUrl);

        // Creating an http connection to communicate with url
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod("POST");
        Log.wtf("JSON","connection started...");
        // Connecting to url

        urlConnection.setRequestProperty("Content-Type", "application/json");

        urlConnection.connect();
        Log.wtf("KOD",Integer.toString(urlConnection.getResponseCode()));
        // Reading data from url
        iStream = new BufferedInputStream(urlConnection.getInputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
        StringBuilder sb = new StringBuilder();
        String line = "";
        while( ( line = br.readLine()) != null){
            sb.append(line);
        }
        data = sb.toString();
        br.close();

    }catch(Exception e){
        Log.wtf("ExceptionWhileUrlDownload", e.toString());
    }finally{
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}

答案 2 :(得分:0)

从服务器发送__proto__可以创建一个JSON对象,如果将密钥转移到另一个对象而不删除__proto__或泄漏敏感数据,则该对象可能会损坏。

它通常以忽略的形式出现在编码的JSON中是不寻常的。这表明在其他地方可能存在问题或纠结。您正在使用的库可能会意外泄漏或利用它。在封闭的系统中使用它可能是可以的,但不允许它进入或退出系统。

// If is optional.
if('__proto__' in obj)
    // This may cause unintended consequences.
    delete(obj.__proto__);

在接收数据时,您还应该非常小心,它不包含__proto__属性。如果将该密钥复制到另一个对象,则可能导致服务器崩溃或损坏。

如果创建您自己的对象,可以使用一些技巧来更改其行为,例如使用defineProperty,但是这些技巧无法完全消除问题。

答案 3 :(得分:0)

随便写

String(<put here your data>)