MySQL 处理SQL注入攻击
如果您通过网页获取用户输入并将其插入到一个MySQL数据库中,则有可能让您对称为SQL注入的安全问题敞开大门。本课将教您如何帮助防止这种情况发生,并帮助您保护脚本和MySQL语句。
比如当你要求用户输入他们的名字,这时候他们给你的不是名字而是一个MySQL语句,那么你可能会在不知不觉中运行这条SQL语句。
永远不要相信用户提供的数据,只在验证后处理此数据.通常,这是通过模式匹配来完成的。在下面的示例中,用户名限制为字母数字混合个字符,加上下划线和长度为8到20个字符—根据需要修改这些规则。if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches))
{
$result = mysql_query("SELECT * FROM users
WHERE username=$matches[0]");
}
else
{
echo "username not accepted";
}
为了演示问题,请考虑以下输入:// supposed input
$name = "Qadir'; DELETE FROM users;";
mysql_query("SELECT * FROM users WHERE name='{$name}'");
函数调用应该从users表中检索记录,其中名称列与用户指定的名称匹配。在正常情况下, $name只包含字母数字字符和空格,例如字符串 ilia。但是在这里,通过将一个全新的查询附加到$name,对数据库的调用变成了灾难:注入的删除查询从用户删除所有记录。
幸运的是,如果使用MySQL ,mysql_query() 函数不允许在单个函数调用中查询堆栈或执行多个查询。如果尝试堆栈查询,则调用失败。
但是,其他PHP数据库扩展,例如SQLite和PostgreSQL,则会愉快地执行堆叠查询,执行一个字符串中提供的所有查询,并产生严重的安全问题。
防止SQL注入:
您可以使用perl和PHP等脚本语言巧妙地处理所有转义字符。PHP的MySQL扩展提供了函数mysql_real_escape_string()以转义对MySQL有特殊意义的字符。if (get_magic_quotes_gpc())
{
$name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM users WHERE name='{$name}'");
Like语句中的注入
like查询时,如果用户输入的值有"_"和"%",则会出现这种情况:用户本来只是想查询"abcd_",查询结果中却有"abcd_"、"abcde"、"abcdf"等等;用户要查询"30%"(注:百分之三十)时也会出现问题。
在PHP脚本中我们可以使用addcslashes()函数来处理以上情况,如下实例:$sub = addcslashes(mysqli_real_escape_string($conn, "%something_"), "%_");
// $sub == \%something\_
mysqli_query($conn, "SELECT * FROM messages WHERE subject LIKE '{$sub}%'");