什么是防止SQL注入的最佳实践

时间:2011-02-26 22:45:53

标签: php sql sql-injection

我做了一些研究但仍然困惑,这是我研究的结果。有人可以评论并建议我如何做得更好,或者如果我已经可以使用坚如磐石的实现了吗?

方法1:

array_map('trim', $_GET);
array_map('stripslashes', $_GET);
array_map('mysql_real_escape_string', $_GET);

方法2:

function filter($data) {
    $data = trim(htmlentities(strip_tags($data)));

    if (get_magic_quotes_gpc())
        $data = stripslashes($data);

    $data = mysql_real_escape_string($data);

    return $data;
}

foreach($_GET as $key => $value) {
    $data[$key] = filter($value);
}

5 个答案:

答案 0 :(得分:13)

您展示的两种方法都不值得推荐

毯子“消毒”数据会适得其反,因为数据需要以不同的方式进行消毒,具体取决于它的使用方式:在数据库查询中使用它需要不同的卫生设施,不能在HTML中输出,或者使用它作为命令行调用等参数。

在使用数据之前,立即采取最佳卫生方式。这样,程序员很容易看到是否所有数据都被实际消毒了。

如果您使用mysql_*系列函数,请对查询中使用的每个参数执行mysql_real_escape_string()

$safe_name = mysql_real_escape_string($_POST["name"]);
$safe_address = mysql_real_escape_string($_POST["address"]);

$result = mysql_query ("INSERT INTO table VALUES '$safe_name', '$safe_address'");

如果您使用PDOmysqli系列函数,则可以使用参数化查询,这可以消除大多数SQL注入问题 - 无论如何都可以解决所有日常问题。

使用mysql_*编写安全查询是完全可能的,并且在PDO查询中引入安全漏洞也是完全可能的,但如果从头开始,请考虑直接使用PDO或mysqli。

仅当您计划在HTML中输出用户输入的数据时才使用strip_tags();请注意,您需要额外执行htmlspecialchars()以可靠地防止XSS攻击。

唯一具有一些优点的全面卫生方法是

 if (get_magic_quotes_gpc())
    $data = stripslashes($data); 

调用过滤掉早期版本的PHP现在已弃用的“魔术引号”功能所添加的转义层。

答案 1 :(得分:1)

我认为这已经足够了(编辑:我们在这里使用$ data表示,例如表单中的一个文本字段,$_POST['example']等):

if (get_magic_quotes_gpc())
    $data = stripslashes($data);

$data = mysql_real_escape_string($data);

我通常在收到$ _POST或$ _GET数据时(在输入测试之前)和后者在编写sql查询之前或期间执行第一次操作。

如果你愿意,可以另外修剪它(也许你并不总是那么想)。但是,最好的解决方案是使用一些库来处理数据库。

答案 2 :(得分:0)

你可以:

  • 使用mysql_real_escape_string(或mysqli_variant)撤消所有用于数据库的用户输入
  • 使用预准备语句(使用mysqli_或PDO)

请注意,如果可能,您应该关闭magic_quotes。如果它打开,只需使用stripslashes(如你的例子中所示),因为它已被弃用,你不应该依赖它。

另请注意,对于不应插入数据库的数据,您不应该这样做,因为它完全没用。

答案 3 :(得分:0)

每当你处理int时,我都喜欢打字; e.g。

$id=(int)$_GET['id'];
if($id<1){//I generally don't pass around 0 or negative numbers
    //Injection Attempt
    die('Go Away');
}
//Continue with the number I **know** is a number

答案 4 :(得分:-1)

好吧,在你的代码中只有mysql_real_escape_string()函数与SQL注入有关。然而,完全错位。
这还不够。

实际上,此功能只能与带引号的字符串一起使用 它对其他一切都没用。因此,在任何其他情况下,应采取其他预防措施。

有关完整说明,请参阅我之前的回答:In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?

您使用的所有其他功能根本与SQL无关 请注意,同时使用strip_tags和htmlentities是多余的。并且htmlentities已经过时了 我只使用htmlspecialchars()而不是这两个,而不是在插入数据库之前,而是在将其发送到浏览器之前。