很难解决sql注入php

时间:2013-08-31 17:37:45

标签: php mysql sql code-injection

以下用于图片缩略图的代码在点击时会通过从数据库中获取“ID”来执行。

echo '<a class="thumbnail" href="view.php?id='.$row['id'] .'"">'; 

以下代码处理通过上述代码传递的GET变量。

<?php
require '../header.php';
if (isset($_GET['id']))
{
require '../../functions/function_db.php';
$id =mysql_real_escape_string (htmlentities($_GET['id']));
$sql = "SELECT * FROM `site_products` WHERE `id` = $id LIMIT 1";
$result = mysql_query($sql);
while ($row = mysql_fetch_assoc($result)) 
{
$product_name = $row['product_name'];
$price = $row['final_price'];
$desc = $row['short_description'];

}
}
?>

尽管使用了mysql_real_escape_string,但在以下情况下,URL会变得易受SQL注入攻击。

http://localhost/cart/pages/men/view.php?id=1'
http://localhost/cart/pages/men/view.php?id=1 orderby 1

并且网页提供以下mysql错误。

 Warning: mysql_fetch_assoc() expects parameter 1 to be resource, boolean given

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

更新,因为Jason McCreary的评论 准备好的语句更安全,但在绑定值时总是强制类型。 但是你仍然需要注意二阶SQL注入它们仍然可能,即使你使用准备好的语句

Id应该是一个整数,只是将它转换为int并过滤掉NULL字节,NULL字节也是邪恶的东西

$id = (int)(str_replace("\0", "", $_GET['id']));

答案 1 :(得分:0)

$id =mysql_real_escape_string (htmlentities($_GET['id']));
$sql = "SELECT * FROM `site_products` WHERE `id` = $id LIMIT 1";

这是mysql_real_escape_string()的常见误用。该函数仅用于转义MySQL查询的单引号字符串。单引号(撇号)应始终围绕返回值。为什么htmlentities()在这里?

将值转换为整数(例如 $id = (int)$_GET['id'];,具有仅保留数字0-9的效果),或者将单引号放在转义值周围,或者更好,切换到mysqliPDO准备好的陈述。

另请参阅:How can I prevent SQL injection in PHP?