【问题标题】:Prepared statements for data out of a database为数据库外的数据准备好的语句
【发布时间】:2017-06-12 15:38:06
【问题描述】:

当用户第一次在我的网站上创建帐户时,他们输入了他们的用户名和密码,这些都是通过准备好的语句放置以防止 SQL 注入。但稍后我将从数据库中获取用户名并在查询中使用它。这仍然让我容易受到攻击吗?我是否也需要为此查询使用准备好的语句?我是否需要对数据库中所有用户输入的信息使用准备好的语句,即使它在第一次输入时已经通过了准备好的语句?是否可以假设在首次输入时通过准备好的语句放置的所有数据都是安全的?

【问题讨论】:

  • 是否有理由避免使用准备好的语句?它只是多了几个字符/几行代码,并保持您的编码一致。
  • 没有,我只是好奇数据是否仍然危险。
  • 是的,可以。 sam' or 1=1 的用户名可能会导致查询出现问题。甚至只是 o'riely 可能会导致问题。

标签: php security mysqli sql-injection


【解决方案1】:

是的,您必须始终使用带有参数绑定的预处理语句。

准备好的语句并不是治愈 SQL 注入的灵丹妙药。他们甚至不阻止 SQL 注入。准备好的语句让您可以使用参数绑定。正是这种 SQL 和数据的分离保护了您免受 SQL 注入。

不安全的预处理语句:

$id = $_GET['id'];
$stmt = $mysqli->prepare("SELECT * FROM park WHERE id=$id");
$stmt->execute();

因为您仍然将变量直接注入 SQL,所以您很容易受到 SQL 注入的攻击。这些变量的内容来自哪里并不重要;正是因为您在 SQL 中使用了未知值,才使其易受攻击。

安全准备好的语句:

$id = $_GET['id'];
$stmt = $mysqli->prepare('SELECT * FROM park WHERE id=?');
$stmt->bind_param('s', $id);
$stmt->execute();

如您所见,我使用了一个占位符,然后使用了名为 bind_param() 的方法。通过这种方式,变量与 SQL 是分开的,并且 SQL 永远不会改变。无论$id 中传递什么值,SQL 都将保持不变。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多