MySQL查询中是否应该引用用户输入的数字以帮助避免SQL注入攻击?
假设我在一页纸上有一张表格,询问某人的年龄。他们输入自己的年龄并点击提交。以下php代码处理表单提交:(age是db表中的int字段。)
$Number = mysqli_real_escape_string($dbc, $_POST["age"]);
$Query = "INSERT INTO details (age) VALUES ($Number)";
$Result = mysqli_query($dbc, $Query);
相反,即使用户输入不是字符串,用单引号括起来会有什么好处吗?像这样:
...
$Query = "INSERT INTO details (age) VALUES ('$Number')"; <-- quotes
...
执行SELECT
怎么样?这是吗
$ID = mysqli_real_escape_string($dbc, $_POST["id"]);
$Query = "SELECT * FROM users WHERE id = '$ID'";
$Result = mysqli_query($dbc, $Query);
优于:
$ID = mysqli_real_escape_string($dbc, $_POST["id"]);
$Query = "SELECT * FROM users WHERE id = $ID"; <-- no quotes
$Result = mysqli_query($dbc, $Query);
注意:我知道准备好的语句,通常在字符串连接中使用它们,但这是我正在处理的遗留代码。我想尽我所能确保它的安全
如果添加数字,请使用intval
/floatval
函数,而不要使用mysql_real_escape_string
函数。
对于使用mysql_real_escape_string
的所有内容,必须使用引号,例如:
$input = "foo'bar";
$input = mysql_real_escape_string($input);
//foo''bar
mysql_query("SELECT $input");
//SELECT foo''bar
//which is still an SQL syntax error.
您真的应该使用sprintf,即使在遗留代码中修改它需要2分钟,在我看来这完全值得。
无耻地从php.net上撕下:
// Formulate Query
// This is the best way to perform an SQL query
// For more examples, see mysql_real_escape_string()
$query = sprintf("SELECT firstname, lastname, address, age FROM friends
WHERE firstname='%s' AND lastname='%s'",
mysql_real_escape_string($firstname),
mysql_real_escape_string($lastname));
// Perform Query
$result = mysql_query($query);
现在,您的查询非常安全,不会被错误的类型传递给它的字段和未标记的特征符。
您应该使用PHP过滤器,并过滤数字-甚至是范围、正则表达式;具有默认值,失败时为NULL等。
http://hu.php.net/manual/en/ref.filter.php
如果值来自请求变量,例如$_POST,请参阅:
http://hu.php.net/manual/en/function.filter-input.php