我不知道如何使这段代码安全。我尝试在查询变量中使用mysql_real_escape_string,例如
$query = "select * from products where id= " . mysql_real_escape_string($products);
但没有奏效,还试图在产品变量中转义,但得到了相同的结果。有什么建议吗?谢谢。
<?php
/ Define vars.
$conn = mysql_connect('localhost', 'test', 'test');
$products = isset($_GET["products"]) ? $_GET["products"] : "";
$query = "select * from products where id=$products";
// List elements.
if ($conn)
{
mysql_select_db('testsqli');
$result = mysql_query($query);
// Table head.
echo '<table cellspacing="5" cellpadding="5">';
echo '<tr>';
echo '<td>Description</td>';
echo '<td>Price</td>';
echo '</tr>';
// Empty table?
if (@mysql_num_rows($result)==0)
{
echo '<tr>';
echo '<td><i>That''s all!</i></td>';
echo '</tr>';
}
// Listing data in table.
while ($row = @mysql_fetch_array($result))
{
echo '<td>'.$row['Description'].'</td>';;
echo '<td>'.$row['Price'].'</td>';;
}
echo '</table>';
}
?>
您仍然需要添加引号(并使用 msqli 代替),如下所示:
$query = "select * from products where id='" . mysqli_real_escape_string($products)."'";
// or
$query = sprintf(
"select * from products where id='%s'",
mysqli_real_escape_string($products)
);
我会使用预准备语句而不是MySQL转义。转义会跳过一些通配符,例如"%"和"*",这也可能会提供意外的结果。
$stmt = $dbh->prepare("SELECT * FROM PRODUCTS WHERE ID=?");
$stmt->bindParam(1, $products, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// call the stored procedure
$stmt->execute();
另外,请记住以下措施可确保其安全:
- 切勿以超级用户或数据库所有者身份连接到数据库。使用具有非常有限权限的始终自定义用户。
- 检查给定的输入是否具有预期的数据类型。(在这种情况下,请验证$products的格式是否符合预期,即,如果您的产品目录只有 9 个字符的索引,请确保它的长度不是 100 个字符。PHP 有广泛的输入验证函数,从变量函数和字符类型函数(例如分别为 is_numeric()、ctype_digit())中最简单的函数,到与 Perl 兼容的正则表达式支持。
- 如果应用程序等待数字输入,请考虑使用 ctype_digit() 验证数据,或使用 settype() 静默更改其类型,或者使用 sprintf() 使用其数字表示形式。
参考: http://php.net/manual/en/security.database.sql-injection.php