我正在使用MySQL API的功能
mysql_real_escape_string()
根据文档,它会转义以下字符:
\0
\n
\r
\
'
"
\Z
现在,我查看了OWASP.org的ESAPI安全库,在Python端口中,它有以下代码(http://code.google.com/p/owasp-esapi-python/source/browse/esapi/codecs/mysql.py):
"""
Encodes a character for MySQL.
"""
lookup = {
0x00 : "\\0",
0x08 : "\\b",
0x09 : "\\t",
0x0a : "\\n",
0x0d : "\\r",
0x1a : "\\Z",
0x22 : '\\"',
0x25 : "\\%",
0x27 : "\\'",
0x5c : "\\\\",
0x5f : "\\_",
}
现在,我想知道是否真的需要转义所有这些角色。我理解为什么%和_在那里,它们是LIKE运算符中的元字符,但我不能简单地理解他们为什么添加退格和制表符字符(\ b \ t)?如果您进行查询,是否存在安全问题:
SELECT a FROM b WHERE c = '...user input ...';
用户输入包含制表符或退格符?
我的问题在于:为什么它们在ESAPI安全库中包含\ b \ t?是否有任何情况,您可能需要转义这些字符?
答案 0 :(得分:46)
关于退格字符的猜测:想象一下,我发送了一封电子邮件“嗨,这是根据需要更新数据库的查询”和带有
的附加文本文件INSERT INTO students VALUES ("Bobby Tables",12,"abc",3.6);
你捕获文件,看到它没关系,然后将文件传输到MySQL。然而,你不知道的是我把
DROP TABLE students;\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b
在INSERT STATEMENT之前你没有看到,因为在控制台输出上,退格会覆盖它。 BAMM!
但只是一个猜测。
编辑(无法抗拒):
答案 1 :(得分:15)
MySQL manual page for strings说:
\0
ASCII NUL(0x00)字符。\'
单引号(“'
”)字符。\"
双引号(“"
”)字符。\b
退格字符。\n
换行符(换行符)。\r
回车符。\t
标签字符。\Z
ASCII 26(Control-Z)。见表格后面的注释。\\
反斜杠(“\
”)字符。\%
“%
”字符。见表格后面的注释。\_
“_
”字符。见表格后面的注释。答案 2 :(得分:4)
如果您有其他选择,黑名单(识别不良角色)绝不是您的选择。
您需要使用白名单,更重要的是绑定参数方法的组合。
虽然这个特定的答案有PHP的重点,但它仍然有很多帮助,并且有助于解释只是通过char过滤器运行字符串在许多情况下不起作用。请见Do htmlspecialchars and mysql_real_escape_string keep my PHP code safe from injection?
答案 3 :(得分:0)
用户输入包含制表符或退格符?
至关重要的是,到目前为止,大多数用户确实认为必须转发用户输入,并且这样的“可以防止注入”。
答案 4 :(得分:0)
Java解决方案:
public static String filter( String s ) {
StringBuffer buffer = new StringBuffer();
int i;
for( byte b : s.getBytes() ) {
i = (int) b;
switch( i ) {
case 9 : buffer.append( " " ); break;
case 10 : buffer.append( "\\n" ); break;
case 13 : buffer.append( "\\r" ); break;
case 34 : buffer.append( "\\\"" ); break;
case 39 : buffer.append( "\\'" ); break;
case 92 : buffer.append( "\\" );
if( i > 31 && i < 127 ) buffer.append( new String( new byte[] { b } ) );
}
}
return buffer.toString();
}
答案 5 :(得分:-2)
不能只从用户输入中删除单引号吗?
例如:1,Func