我在这里看到一些人指出,使用mysql_real_escape_string
串联查询不会(完全)保护您免受SQL注入(inject)攻击。
但是,我还没有看到一个输入示例,该示例说明了mysql_real_escape_string
不能保护您免受攻击的攻击。大多数示例都忘记了mysql_query
仅限于一个查询,并且错误地使用了mysql_real_escape_string
。
我能想到的唯一示例如下:
mysql_query('DELETE FROM users WHERE user_id = '.mysql_real_escape_string($input));
这不会保护您免受以下输入的影响:
5 OR 1=1
我认为这是对
mysql_real_escape_string
的不正确使用,而不是缺点,它是为字符串而非数字值设计的。您应该强制转换为数字类型,或者如果要在 sanitizer 时将输入视为字符串,则应在查询中执行相同的操作,并在其两边使用引号引起来。谁能提供一个输入示例,它可以绕过
mysql_real_escape_string
而不依赖于对数值的不正确处理,或者忘记mysql_query
只能执行一个查询?编辑:我对
mysql_real_escape_string
的局限性感兴趣,并且没有将其与替代项进行比较,我意识到新项目有更好的选择,并且对此没有争议。 最佳答案
mysql_real_escape_string
或mysql_扩展名的主要缺点是,与其他更现代的API(尤其是预准备的语句)相比,很难正确地应用它。 mysql_real_escape_string
应该仅在一种情况下使用:转义用作引号之间SQL语句中的值的文本内容。例如。:
$value = mysql_real_escape_string($value, $link);
$sql = "... `foo` = '$value' ...";
^^^^^^
mysql_real_escape_string
确保上述上下文中的$value
不会弄乱SQL语法。它不起作用,您可能会在这里想到:$sql = "... `foo` = $value ...";
或在这里:
$sql = "... `$value` ...";
或在这里:
$sql = mysql_real_escape_string("... `foo` = '$value' ...");
如果将其应用于在除SQL语句中带引号的字符串之外的任何上下文中使用的值,则该值将被错误地使用,并且可能会或可能不会弄乱所得的语法和/或允许某些人提交可能启用SQL注入(inject)攻击的值。
mysql_real_escape_string
的用例非常狭窄,但是很少能正确理解。使用
mysql_real_escape_string
陷入困境的另一种方法是使用错误的方法设置数据库连接编码。你应该做这个:mysql_set_charset('utf8', $link);
您也可以这样做:
mysql_query("SET NAMES 'utf8'", $link);
问题在于后者绕过了mysql_ API,后者仍然认为您正在使用
latin1
(或其他方式)与数据库进行通信。现在使用mysql_real_escape_string
时,它将假定错误的字符编码和转义字符串,与数据库稍后解释它们的方式不同。通过运行SET NAMES
查询,您在mysql_客户端API如何处理字符串与数据库如何解释这些字符串之间创建了一条裂痕。这可以用于某些多字节字符串情况下的注入(inject)攻击。如果正确应用,我知道
mysql_real_escape_string
中没有基本的注入(inject)漏洞。 但是,主要的问题是,错误地应用它非常容易,这会带来漏洞。关于php - mysql_real_escape_string的缺点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12703420/