为什么较新版本的节点不从请求正文中删除 __proto__?
Why don't newer versions of node remove __proto__ from request body?
当我向我的快递服务器发送 PUT
请求时,req.body
有时会有 __proto__
属性,而其他时候则没有。
使用节点 0.10.26 并表示 3.2.3:
- 当我输入
{"a":"b", "__proto__": {}}
,
- 那么
req.body
就是{"a":"b"}
使用节点 4.1.0 并表示 3.2.3:
- 当我输入
{"a":"b", "__proto__": {}}
,
- 那么
req.body
就是{"a":"b", "__proto__": {}}
因此较新版本的节点不会删除 __proto__
属性。我真的很喜欢这种行为;现在我必须编写自己的中间件来去除 属性。我认为这与bodyparser
有关。但是,奇怪的是,两个测试都具有相同版本的 express
(因此具有相同版本的 bodyparser
)。
任何人都可以给出改变的动机吗?推荐的解决方法是什么?
express 和 node 均不对此行为负责。为了兼容性和规范一致性,这实际上在 V8 很久以前就已经更改了。
旧行为(__proto__
被剥离):
> var x = JSON.parse('{"__proto__":[]}');
> x.hasOwnProperty('__proto__');
false
新行为(__proto__
未剥离):
> var x = JSON.parse('{"__proto__":[]}');
> x.hasOwnProperty('__proto__');
true
来源:
- https://code.google.com/p/chromium/issues/detail?id=115055
- https://code.google.com/p/v8/issues/detail?id=1310
解决方案:
就像你说的,你可以自己写一个简单的中间件来剥离 属性:
function stripProto(req, res, next) {
delete req.body.__proto__;
next();
}
// ...
app.use(stripProto);
当我向我的快递服务器发送 PUT
请求时,req.body
有时会有 __proto__
属性,而其他时候则没有。
使用节点 0.10.26 并表示 3.2.3:
- 当我输入
{"a":"b", "__proto__": {}}
, - 那么
req.body
就是{"a":"b"}
使用节点 4.1.0 并表示 3.2.3:
- 当我输入
{"a":"b", "__proto__": {}}
, - 那么
req.body
就是{"a":"b", "__proto__": {}}
因此较新版本的节点不会删除 __proto__
属性。我真的很喜欢这种行为;现在我必须编写自己的中间件来去除 属性。我认为这与bodyparser
有关。但是,奇怪的是,两个测试都具有相同版本的 express
(因此具有相同版本的 bodyparser
)。
任何人都可以给出改变的动机吗?推荐的解决方法是什么?
express 和 node 均不对此行为负责。为了兼容性和规范一致性,这实际上在 V8 很久以前就已经更改了。
旧行为(
__proto__
被剥离):> var x = JSON.parse('{"__proto__":[]}'); > x.hasOwnProperty('__proto__'); false
新行为(
__proto__
未剥离):> var x = JSON.parse('{"__proto__":[]}'); > x.hasOwnProperty('__proto__'); true
来源:
- https://code.google.com/p/chromium/issues/detail?id=115055
- https://code.google.com/p/v8/issues/detail?id=1310
解决方案:
就像你说的,你可以自己写一个简单的中间件来剥离 属性:
function stripProto(req, res, next) {
delete req.body.__proto__;
next();
}
// ...
app.use(stripProto);