MySQL数据库防SQL注入原理

每个语言都有自己的数据库框架或库,无论是哪种语言,哪种库,它们在数据库防注入方面使用的技术原理无外乎下面介绍的几种方法。

一、特殊字符转义处理

Mysql特殊字符指在mysql中具有特殊含义的字符,除了%_是mysql特有的外,其他的和我们在C语句中接触的特殊字符一样。

特殊字符转义字符特殊意义
\0\\0字符串结束符NUL
'\'单引号
"\"双引号
\b\\b退格
\n\\n换行
\r\\r回车
\Z\\ZControl+Z
\\\反斜杠
%\%百分号,模糊查询中匹配任意个任意字符
_\_下划线,模糊查询中匹配单个任意字符

mysql C API提供了mysql_real_escape_string函数对转义字符进行处理,但根据实际经验,在使用该API时会产生诸多问题。
因此自己实现了一个类似的函数:

std::string MysqlEscapeString(const std::string &strSql) {
        size_t iSrcSize = strSql.size();
        std::string strDest;
        for (size_t i = 0; i < iSrcSize; i++) {
            char ch = strSql[i];
            switch (ch)
            {
            case '\0':
                strDest.append("\\0");
                break;
            case '\n':
                strDest.append("\\n");
                break;
            case '\r':
                strDest.append("\\r");
                break;
            case '\'':
                strDest.append("\\'");
                break;
            case '"':
                strDest.append("\\\"");
                break;
            case '\\':
                strDest.append("\\\\");
                break;
            case '%':
                strDest.append("\\%");
                break;
            case '_':
                strDest.append("\\_");
                break;
            default:
                strDest.append(1, ch);
                break;
            }
        }

        return strDest;
    }

对于%_这2个只在模糊查询条件中有特殊含义,而在普通字符串中没有其他含义的字符,需要根据字符使用在SQL语句中的具体位置来决定是否需要处理。如我们要查询memberName包含t_st的用户信息:

select * from member where memberName like '%t_st%;

如果不对_进行转义处理则会查询出:

test
tast
tbst
t_st

二、Prepared SQL Statement(预处理语句)

SET @sql = "SELECT * FROM member WHERE memberName like ?";
SET @param = '%t_st%';

PREPARE stmt FROM @sql;
EXECUTE stmt using @param;
DEALLOCATE PREPARE stmt; 

使用这种方法需要注意以下2点:
1) ?占位符不能用在字符串中,上面例子如果写成下面这样是错误的。

SET @sql = "SELECT * FROM member WHERE memberName like '%?%'";
SET @param = 't_st';

PREPARE stmt FROM @sql;
EXECUTE stmt using @param;
DEALLOCATE PREPARE stmt; 

2) EXECUTE stmt USING @param;中使用的@param变量,是会话级别的变量。该变量的作用域至整个连接,连接断开之后该变量才会释放。重复使用相同变量时要留意了。

转载于:https://www.cnblogs.com/jiangxueqiao/p/7444127.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值