应该在MySQL查询中引用来自用户输入的数字以帮助避免SQL注入攻击?
应该在MySQL查询中引用来自用户输入的数字以帮助避免SQL注入攻击?应该在MySQL查询中引用来自用户输入的数字以帮助避免SQL注入攻击?
说我有一个页面上的表格,要求某人的年龄。他们进入他们的年龄,并提交。与表单提交下面的PHP代码的交易:(年龄在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"; <-- no quotes
$Result = mysqli_query($dbc, $Query);
注:
$ID = mysqli_real_escape_string($dbc, $_POST["id"]);
$Query = "SELECT * FROM users WHERE id = '$ID'";
$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);
您的查询已经非常安全,从被传递了错误的类型到它的领域和转义caracters。
**为什么**是sprintf更好? – Jeff 2011-06-07 18:18:28
优点可以是更好的可读性(取决于),它是实际准备语句路上的第一步(即,如果您改变它,重写起来更容易)。 – Wrikken 2011-06-07 18:31:24
@ user569090因为它会筛选传递给您的查询的值。你的领域是int?它将始终接收int。你的领域是一个字符串? Sprintf会将这个参数传递给你。还有很多格式化选项可用于金钱格式,0填充等等,尽管我很少使用这些格式,但他们有时候可以很方便。 – stefgosselin 2011-06-07 18:43:17
你应该使用PHP的过滤器和过滤的号码 - 即使是范围,正则表达式;具有默认值,NULL上故障等
http://hu.php.net/manual/en/ref.filter.php
如果值来自请求变量,例如$ _POST,请参阅:
对于intval引用+1:当您希望发布整数时,通过将其转换为intval来验证它实际上是一个整数。 – Jeff 2011-06-07 18:23:52
那么你会在SQL字符串中加上int引号吗? – 2011-06-07 20:24:42
对不起,如果我不清楚:数字应该被转换为数字(intval/floatval),并且_not_不使用引号,并且mysql_real_escape_string不起作用。然而,如果你不这样做,只是在所有事情上都使用'mysql_real_escape_string'(一些框架/库甚至做到这一点),你就必须在这些字符串周围使用引号(介意你,字符串,而不是数字)。我想不出一种方式,否则会导致有用的SQL注入,但它仍然可能导致无效的查询。 – Wrikken 2011-06-07 20:28:49