function Query()
{
$args = func_get_args ();
if (sizeof ($args) > 0)
{
$query = $args[0];
for ($i = 1; $i < sizeof ($args); $i++)
$query = preg_replace ("/\?/", "'" . mysql_real_escape_string ($args[$i]) . "'", $query, 1);
}
else
{
return FALSE;
}
我有这样的功能。基本上,我这样做一个查询:
$this->Query('SELECT * FROM USERS WHERE Username = ? AND Points < ?', $username, $points);
它目前支持已弃用的mysql
函数,但适应mysqli
就像在我的班级中用mysql
替换mysqli
一样简单。
这是一种依赖SQL注入攻击的安全方法吗?每个问号都由mysql_real_escape_string
自动清理,之前我从未遇到过问题,但是我应该使用mysqli_real_escape_string
进行清理吗?
我知道有关mysqli的预处理语句,但对每个变量使用bindParam
似乎对我来说有点过分了。
您怎么看?
答案 0 :(得分:2)
使用绑定参数不过度杀伤,应该是必需的。它将更有效地逃脱并准备您的参数。
$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);
$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;
/* execute prepared statement */
mysqli_stmt_execute($stmt);
那真的看起来有点矫枉过正吗?
答案 1 :(得分:1)
今天非常棒的一天 - 第二次尝试连续创建合理的数据库抽象层。
我应该使用mysqli_real_escape_string进行清理吗?
<强>不。强>
仅仅因为这个功能没有消毒任何东西。
但要格式化 SQL字符串文字这个函数是必须的,无法避免或替换。
因此,您正是以正确的方式使用此功能,格式化字符串仅并格式化无条件。
那么,只要您可以使用?,您就可以查询完全安全。标记以替换实际数据(并且 - 甚至使得nitpick抱怨空闲 - 只要您使用mysql(i)_set_charset()
函数设置SQL编码)。
如果有人将您的方法称为已损坏 - 只需向他们询问完整代码段的证明代码即可显示某个漏洞。
但是,让我提请你注意几件重要的事情。
动态SQL查询部分不仅限于字符串。例如,这两个查询不适用于您的函数:
SELECT * FROM table LIMIT ?,?
SELECT * FROM table ORDER BY ?
仅因为数字和标识符需要不同的格式 因此,最好使用类型提示的占位符来告诉您的函数,应用哪种格式
请看一下my class,它基于与你相同的原则,但我上面提到了改进。我希望你会发现它有用或者至少值得借用一两个想法。
答案 2 :(得分:0)
如果您现在使用mysqli而不是mysql。最好使用mysqli_real_escape_string。 请注意params命令已被修改。 (%和_仍未转义)