是否应在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);
注意:我知道准备好的语句,并且通常在字符串连接中使用它们,但这是我正在处理的遗留代码。我希望尽可能地保护它。
答案 0 :(得分:3)
如果您添加号码,请使用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.
答案 1 :(得分:1)
你真的应该使用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);
您的查询现在非常安全,不会将错误的类型传递给它的字段和未转义的字符。
答案 2 :(得分:0)
你应该使用PHP过滤器,并过滤数字 - 甚至是范围,正则表达式;默认值,失败时为NULL等
http://hu.php.net/manual/en/ref.filter.php
如果值来自请求变量,例如$ _POST,见: