2011-06-07 27 views
0

应该在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); 

不比我知道准备的语句,通常使用它们在字符串连接,但是这是遗留代码我处理。我想尽可能保证它的安全。

回答

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. 
+0

对于intval引用+1:当您希望发布整数时,通过将其转换为intval来验证它实际上是一个整数。 – Jeff 2011-06-07 18:23:52

+0

那么你会在SQL字符串中加上int引号吗? – 2011-06-07 20:24:42

+0

对不起,如果我不清楚:数字应该被转换为数字(intval/floatval),并且_not_不使用引号,并且mysql_real_escape_string不起作用。然而,如果你不这样做,只是在所有事情上都使用'mysql_real_escape_string'(一些框架/库甚至做到这一点),你就必须在这些字符串周围使用引号(介意你,字符串,而不是数字)。我想不出一种方式,否则会导致有用的SQL注入,但它仍然可能导致无效的查询。 – Wrikken 2011-06-07 20:28:49

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); 

您的查询已经非常安全,从被传递了错误的类型到它的领域和转义caracters。

+0

**为什么**是sprintf更好? – Jeff 2011-06-07 18:18:28

+0

优点可以是更好的可读性(取决于),它是实际准备语句路上的第一步(即,如果您改变它,重写起来更容易)。 – Wrikken 2011-06-07 18:31:24

+0

@ user569090因为它会筛选传递给您的查询的值。你的领域是int?它将始终接收int。你的领域是一个字符串? Sprintf会将这个参数传递给你。还有很多格式化选项可用于金钱格式,0填充等等,尽管我很少使用这些格式,但他们有时候可以很方便。 – stefgosselin 2011-06-07 18:43:17

相关问题