codecamp

Node.js NoSQL操作

1.10.1 【必须】校验参数值类型

  • 将HTTP参数值代入NoSQL操作前,应校验类型。如非功能需要,禁止对象(Object)类型传入。

// bad:执行NOSQL操作前,未作任何判断
app.post("/", (req, res) => {
    db.users.find({ username: req.body.username, password: req.body.password }, (err, users) => {
    // **TODO:** handle the rest
    });
});


// good:在进入nosql前先判断`__USER_INPUT__`是否为字符串。
app.post("/", (req, res) => {
    if (req.body.username && typeof req.body.username !== "string") {
        return new Error("username must be a string");
    }
    if (req.body.password && typeof req.body.password !== "string") {
        return new Error("password must be a string");
    }
    db.users.find({ username: req.body.username, password: req.body.password }, (err, users) => {
        // **TODO:** handle the rest
    });
});

为什么要这么做?

JavaScript中,从http或socket接收的数据可能不是单纯的字符串,而是被黑客精心构造的对象(Object)。在本例中:

- 期望接收的POST数据:username=foo&password=bar
- 期望的等价条件查询sql语句:select * from users where username = 'foo' and password = 'bar'
- 黑客的精心构造的攻击POST数据:username[$ne]=null&password[$ne]=null或JSON格式:{"username": {"$ne": null},"password": {"$ne": null}}
- 黑客篡改后的等价条件查询sql语句:select * from users where username != null & password != null
- 黑客攻击结果:绕过正常逻辑,在不知道他人的username/password的情况登录他人账号。

1.10.2 【必须】NoSQL操作前,应校验权限/角色

  • 执行NoSQL增、删、改、查逻辑前,应校验权限

// 使用express、mongodb(mongoose)实现的删除文章demo
// bad:在删除文章前未做权限校验
app.post("/deleteArticle", (req, res) => {
    db.articles.deleteOne({ article_id: req.body.article_id }, (err, users) => {
        // TODO: handle the rest
    });
});


// good:进入nosql语句前先进行权限校验
app.post("/deleteArticle", (req, res) => {
    checkPriviledge(ctx.uin, req.body.article_id);
    db.articles.deleteOne({ article_id: req.body.article_id }, (err, users) => {
        // TODO: handle the rest
    });
});

关联漏洞:高风险 - 越权操作,高风险 - NoSQL注入

Node.js SQL 操作
Node.js 服务器端渲染(SSR)
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }