Node.js 解决sql注入问题

这段时间维护Node.js编写的项目,发现登陆SQL注入问题。经过一番折腾解决了这个问题,现记录如下:

一、问题描述 

const crypto = require('crypto');
const conn = require('../../libs/Conn');
const mysql = require('mysql');

module.exports = async function (params) {
    let hash = crypto.createHash('sha256');
    let login_name = params.login_name;
    let password = hash.update(params.password).digest('hex');
    let sql = `SELECT uf.* FROM user_file uf WHERE uf.login_name = '${login_name}' AND uf.password = '${password}' AND
              uf.delete_sign = 1;
        `;
    let user = (await conn(sql)).shift();
    return user;
};

这样的方式很容易被人在动态参数中加入特殊字符产生sql注入,威胁数据库的安全。

如果 login_name 输入'or'1'='1,SQL语句会变成  uf.login_name = '' or '1' = '1' AND uf.password = ' ' 

也就是说不需要知道登录名,只要输密码就可以。


二、解决方案

如果对参数使用escape,就能将参数中的特殊字符进行转义,防止sql的注入。

WHERE uf.login_name = `+ mysql.escape(login_name) +` AND uf.password = `+ mysql.escape(password) +` 

三、拓展

   3.1 使用escape()对传入参数进行编码

mysql.escape(param)

connection.escape(param)

pool.escape(param)

  3.2 escape()方法编码规则如下

   
    Numbers不进行转换;
    Booleans转换为true/false;
    Date对象转换为’YYYY-mm-dd HH:ii:ss’字符串;
    Buffers转换为hex字符串,如X’0fa5’;
    Strings进行安全转义;
    Arrays转换为列表,如[‘a’, ‘b’]会转换为’a’, ‘b’;
    多维数组转换为组列表,如[[‘a’, ‘b’], [‘c’, ‘d’]]会转换为’a’, ‘b’), (‘c’, ‘d’);
    Objects会转换为key=value键值对的形式。嵌套的对象转换为字符串;
    undefined/null会转换为NULL;
    MySQL不支持NaN/Infinity,并且会触发MySQL错误。

参考:https://blog.csdn.net/lin_tuer/article/details/54809330

你可能感兴趣的:(js,nodejs,sql)