为了账号安全,请及时绑定邮箱和手机立即绑定

如何在PHP中阻止SQL注入?

如何在PHP中阻止SQL注入?

暮色呼如 2019-05-20 13:40:34
如果插入用户输入而不修改SQL查询,则应用程序容易受到SQL注入的攻击,如下例所示:$unsafe_variable = $_POST['user_input']; mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");这是因为用户可以输入类似的内容value'); DROP TABLE table;--,查询变为:INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')可以采取哪些措施来防止这种情况发生?
查看完整描述

7 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

如果您使用的是最新版本的PHP,则mysql_real_escape_string下面列出的选项将不再可用(尽管mysqli::escape_string它是现代版本)。这些天,该mysql_real_escape_string选项只适用于旧版PHP上的遗留代码。


您有两个选项 - 转义您的特殊字符unsafe_variable,或使用参数化查询。两者都可以保护您免受SQL注入。参数化查询被认为是更好的做法,但在使用它之前需要在PHP中更改为更新的MySQL扩展。

我们将首先覆盖较低影响的字符串。

//Connect$unsafe_variable = $_POST["user-input"];$safe_variable = mysql_real_escape_string($unsafe_variable);mysql_query("INSERT INTO table
 (column) VALUES ('" . $safe_variable . "')");//Disconnect

另请参见mysql_real_escape_string功能的详细信息。

要使用参数化查询,您需要使用MySQLi而不是MySQL函数。要重写您的示例,我们需要类似以下内容。

<?php
    $mysqli = new mysqli("server", "username", "password", "database_name");

    // TODO - Check that connection was successful.

    $unsafe_variable = $_POST["user-input"];

    $stmt = $mysqli->prepare("INSERT INTO table (column) VALUES (?)");

    // TODO check that $stmt creation succeeded

    // "s" means the database expects a string
    $stmt->bind_param("s", $unsafe_variable);

    $stmt->execute();

    $stmt->close();

    $mysqli->close();?>

你想要阅读的关键功能就是mysqli::prepare

此外,正如其他人所建议的那样,您可能会发现使用PDO之类的步骤来增加抽象层是有用的/更容易的。

请注意,您询问的案例非常简单,更复杂的案例可能需要更复杂的方法。特别是:

  • 如果要根据用户输入更改SQL的结构,参数化查询将无济于事,并且不需要转义所需的转义mysql_real_escape_string。在这种情况下,您最好通过白名单传递用户的输入,以确保只允许“安全”值。

  • 如果您在条件中使用来自用户输入的整数并采用该mysql_real_escape_string方法,您将在下面的注释中遇到Polynomial描述的问题。这种情况比较棘手,因为整数不会被引号括起来,所以你可以通过验证用户输入只包含数字来处理。

  • 可能还有其他我不知道的情况。您可能会发现是一个有用的资源,可以解决您可能遇到的一些更微妙的问题。


查看完整回答
反对 回复 2019-05-20
?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

我建议使用PDO(PHP数据对象)来运行参数化SQL查询。

这不仅可以防止SQL注入,还可以加快查询速度。

通过使用PDO,而不是mysql_mysqli_pgsql_功能,你让你的应用程序从数据库中多了几分抽象的,因为你必须选择数据库提供者很少发生。


查看完整回答
反对 回复 2019-05-20
?
临摹微笑

TA贡献1982条经验 获得超2个赞


使用PDO和准备的查询。


($conn是一个PDO对象)


$stmt = $conn->prepare("INSERT INTO tbl VALUES(:id, :name)");

$stmt->bindValue(':id', $id);

$stmt->bindValue(':name', $name);

$stmt->execute();


查看完整回答
反对 回复 2019-05-20
  • 7 回答
  • 0 关注
  • 616 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信