【问题标题】:mysqli_prepare as a check to prevent SQL Injection [closed]mysqli_prepare 作为检查以防止 SQL 注入 [关闭]
【发布时间】:2013-06-03 14:35:13
【问题描述】:

我目前正在编写一个应用程序,该应用程序需要针对 SQL 注入的可靠安全性。我的问题是这个。将输入参数与准备语句分开以防止 SQL 注入是绝对要求,还是您可以简单地准备任何语句以确保它没有 SQL 注入?

换句话说,我可以使用 mysqli_prepare 作为一个简单的检查来确保在我之前构建的语句中没有注入 SQL 吗?或者是绑定参数的整个过程,并使用后续返回的语句结构来处理服务器返回的信息?

【问题讨论】:

标签: php sql code-injection


【解决方案1】:

是否绝对需要将输入参数与准备语句分开以防止 SQL 注入

或多或少。

您可以使用其他技术来保护自己,有时您必须使用它们,但在准备好的声明中使用? 10 次中有 9 次是最简单、最清晰且通常最好的解决方案。

或者您可以简单地准备任何语句以确保它没有 SQL 注入?

没有。如果您在准备语句之前将用户数据混合在一起以创建有害的 SQL,那么准备语句根本不会为您提供任何保护。

保护来自绑定参数,而不是来自准备好的语句。这两件事通常是齐头并进的,因此有时会将各自的好处错误地归因于错误的功能。

【讨论】:

  • 你的意思是,如果他在将查询输入到Prepared Statement之前构造查询,它仍然容易受到SQL注入 - 这是真的。
【解决方案2】:

如果你的意思是这样的:

$sql = "SELECT foo FROM bar WHERE baz = '$var'";
$query = $db->prepare($sql);
// Wee, we are safe!

然后:否。

假设$var 包含这个:

Robert'; DROP TABLE users; --

$sql 的值将是:

SELECT foo FROM bar WHERE baz = 'Robert'; DROP TABLE users; --'

然后没有人能够分辨出该语句的哪一部分是由用户插入的,以及它的意图是什么。事后准备这个查询是没有意义的。

【讨论】:

  • 还可能值得一提的是,' OR 1 = 1; -- 是一个更好的例子,因为这些天多查询几乎消失了
  • 嗯,我只是以 Bobby Tables 为例。 :-3
【解决方案3】:

准备语句是由 SQL 引擎完成的。您提前向服务器发送查询,例如:

Prepare : SELECT id, x FROM y WHERE id = ?

然后,? 绑定数据;您的抽象层甚至也可以强类型化(PDO 可以做到这一点,因为您可以让它在格式化和输入数据之前进行显式转换)

在准备中,数据和语句(查询)是完全分开的。该查询正在服务器上等待,准备好被调用,如果存在数据字段,它将等待输入。

这有一个主要好处,因为您可以完全分离逻辑和数据,还因为查询存储在服务器上,随时可以调用。这意味着,如果您必须为大量插入数据调用数千次查询,那么最好为性能做好准备。

仅仅准备一个已经包含用户输入的语句并不能保证安全。您必须在添加用户输入之前分离数据和逻辑。

【讨论】:

  • 附带说明,占位符始终是强类型的。如果未指定类型,根据我的经验,它们通常默认为字符串,当然,会对其进行处理以防止 SQL 引擎注入。
  • @crush PDO 在传递变量时默认为PDO::PARAM_STR,mysqli 似乎也默认为字符串
  • 默认使用字符串是有道理的,因为字符串最容易被滥用。
【解决方案4】:

在将参数发送到服务器时,最好使用准备好的语句。 没有理由不。这是防止 SQL 注入的绝对最低限度。

当然,如果不发送参数,SQL注入就不是问题。

【讨论】:

  • 有时,无需用户输入的简单查询内容的维护和编写要简单得多,但这些是规则的例外。
  • 这是对的,但这并不是关于防止 SQL 注入问题的真正答案。如果没有参数被发送,那么首先就没有 SQL 注入。
猜你喜欢
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 2012-07-30
相关资源
最近更新 更多