在 PHP 中使用准备好的语句/存储过程时,如何保护自己免受 SQL 注入?

发布于 2024-11-18 00:15:33 字数 847 浏览 2 评论 0原文

自从阅读此 mysql_real_escape_string 足以防 SQL 注入吗?

我见过这个非常好的线程 如何防止 PHP 中的 SQL 注入?

我经常这样做桌面/内部工具上的 ms sql server 东西,我们总是编写存储过程来防止这种情况,所以我使用 PDO http://php.net/manual/en/pdo.prepared-statements.php< /a>

上面有一行:

准备好的语句的参数不需要加引号;驱动程序会自动处理这个问题。如果应用程序专门使用准备好的语句,则开发人员可以确保不会发生 SQL 注入(但是,如果查询的其他部分是使用未转义的输入构建的,则 SQL 注入仍然是可能的)。

我一直相信 PDO 确实可以防止 sql 注入攻击,所以任何人都可以提供一个从安全角度来看 PDO 不够的实例吗?

I've been looking at how best to protect against sql injection in PHP/mysql beyond just using the mysqli/mysql real escape since reading this Is mysql_real_escape_string enough to Anti SQL Injection?

I have seen this very good thread How can I prevent SQL injection in PHP?

I use to do alot of ms sql server stuff on the desktop/internal tools, we always wrote stored procedures to protect against this so I read up on the equivalent in PHP/mysql using PDO http://php.net/manual/en/pdo.prepared-statements.php

In the above there is the line :

The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).

I've been lead to believe that PDO do protect against sql injection attacks so can anyone provide a instance where PDO isnt sufficient from a security standpoint?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

流年里的时光 2024-11-25 00:15:33

您仍然可以从内部使用 PREPARE 语法(在 MySQL 中)创建动态 SQL 语句的存储过程获取 SQL 注入。

这些需要非常小心地完成,必要时使用 QUOTE()。

理想情况下,我们不需要在存储例程中使用 PREPARE,但在某些情况下它变得很难避免:

  • 在 MySQL 5.5 之前,LIMIT 子句不能使用非常量值。
  • IN() 子句中使用的列表不能(明智地)参数化,因此如果使用此模式,则需要使用动态 SQL
  • 有时需要使用动态生成的 ORDER BY 子句。

在有必要使用 PREPARE 的情况下,那么我会建议,按优先顺序:

  • 如果某物是 INT 类型(等),则它不易受到 SQL 注入的影响,并且您可以将值放入查询中,而无需使用问题(例如对于 LIMIT)
  • 字符串值可以在 EXECUTE 之前放入 @variable 中,或者传递到 EXECUTE 子句
  • 列表值(例如对于 IN())需要检查有效性。
  • 最后,QUOTE() 可用于引用字符串值,这在某些情况下很有用

You can still get SQL injections from stored procedures which are internally using the PREPARE syntax (in MySQL) to create dynamic SQL statements.

These need to be done with extreme care, using QUOTE() as necessary.

Ideally, we should not need to use PREPARE in stored routines, but in certain cases it becomes very difficult to avoid:

  • Prior to MySQL 5.5, the LIMIT clause cannot use non-constant values.
  • Lists used in an IN() clause cannot be (sensibly) parameterised, so you need to use dynamic SQL if this pattern is used
  • It is sometimes desirable to use dynamically generated ORDER BY clauses.

etc

In the case where it is necessary to use PREPARE, then I would recommend, in order of preference:

  • If something is an INT type (etc) it is not susceptible to SQL injection, and you can place the value into the query without a problem (e.g. for LIMIT)
  • String values can be placed into an @variable before the EXECUTE, or passed in to the EXECUTE clause
  • List-values (for example for IN()) need to be checked for validity.
  • Finally, QUOTE() can be used to quote string values, which can be useful in some cases
掩耳倾听 2024-11-25 00:15:33

起决定性作用的不是您使用的结构(存储过程、准备好的语句等),而是您是否在任何时候使用未经检查的用户输入将 SQL 连接在一起。例如,您可以从存储过程中执行动态 SQL,在这种情况下危险仍然存在。

最简单的方法(从避免注入的角度来看)是使用带有绑定变量的 SP 或 PS:这些不需要检查,因为它们将被识别为预定义占位符内的值。

It's not the structure you use (stored procedures, prepared statements etc.) that is decisive, but whether you are at any point concatenating SQL together using unchecked user input. For example, you can execute dynamic SQL from within a stored procedure, in which case the danger is still there.

The easiest way (from the injection-avoidance point of view) is to use SPs or PSs with bound-in variables: these do not need to be checked as they will be recognized as values to go within a predefined placeholder.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文