每个语言都有自己的数据库框架或库,无论是哪种语言,哪种库,它们在数据库防注入方面使用的技术原理无外乎下面介绍的几种方法。
Mysql 特殊字符指在 mysql 中具有特殊含义的字符,除了
和
- %
是 mysql 特有的外,其他的和我们在 C 语句中接触的特殊字符一样。
- _
特殊字符 | 转义字符 | 特殊意义 |
---|---|---|
|
|
字符串结束符 NUL |
|
|
单引号 |
|
|
双引号 |
|
|
退格 |
|
|
换行 |
|
|
回车 |
|
|
Control+Z |
|
|
反斜杠 |
|
|
百分号,模糊查询中匹配任意个任意字符 |
|
|
下划线,模糊查询中匹配单个任意字符 |
mysql C API 提供了
函数对转义字符进行处理,但根据实际经验,在使用该 API 时会产生诸多问题。 因此自己实现了一个类似的函数:
- mysql_real_escape_string
- 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
- 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)
中使用的 @param 变量,是会话级别的变量。该变量的作用域至整个连接,连接断开之后该变量才会释放。重复使用相同变量时要留意了。
- EXECUTE stmt USING @param;
来源: http://www.cnblogs.com/jiangxueqiao/p/7444127.html