【问题标题】:How is SQL Injection Possible When Using Bind Variables?使用绑定变量时如何进行 SQL 注入?
【发布时间】:2017-08-31 07:08:00
【问题描述】:

使用绑定变量时如何进行 SQL 注入?

我的 DBA 说使用绑定变量并不能完全防止 SQL 注入,但我不知道这是怎么回事,因为绑定变量(尤其是字符串)通常会强制注入的 SQL 成为字符串在WHERE 子句中。

例子:

SELECT CUST_ID  
FROM CUST.CUSTOMER 
WHERE FIRST_NAME=:FNAME;

如果FNAME="SELECT FNMAME WHERE CUST_ID=10040",数据库将运行以下查询

SELECT CUST_ID 
FROM CUST.CUSTOMER 
WHERE FIRST_NAME="SELECT FNMAME WHERE CUST_ID=10040";

这将返回 0 行。

我在互联网上搜索了这个问题的答案,甚至搜索了这个网站,但我找不到。

再次感谢。

【问题讨论】:

  • 您是否请您的 DBA 解释他们的意思?
  • 如果您的 DBA 是正确的(他们不是),针对您的查询的 SQL 注入攻击尝试可能类似于 FNAME=SMITH' OR CUST_ID=10040 OR 'X'='X
  • @AlexPoole,我的 DBA 说他在某处读过这篇文章,但必须具体找到他读到的地方。

标签: sql oracle sql-injection


【解决方案1】:

严格来说,SQL 注入在使用绑定变量时确实是可能的。下面的查询使用 BV 并且可以成为SQL注入的主题,以防参数column_list被操纵。

 'select' + column_list + ' from T where col :1'

所以缺少的是使用绑定变量 在静态查询中并避免使用参数的语句连接,例如用于列列表。

【讨论】:

  • 这就是我的 DBA 所说的。
【解决方案2】:

说到常规查询,Mysql/PDOtwo known edge cases,两者都与Oracle无关。

说到存储过程,当然有could be a problem 在存储过程本身,但我认为要么是不相关的情况,要么是使用准备好的语句不一致。

因此,您的 DBA 很可能只是在某个地方听到了一些谣言,但不知道他在说什么。

【讨论】:

    【解决方案3】:

    查询参数不可能“破坏”并允许在参数化查询中进行 SQL 注入。但确实参数绑定并没有为所有可能的动态查询提供解决方案。也许这就是你的 DBA 的意思(你为什么不问她?)。

    考虑这个查询:

    SELECT CUST_ID FROM CUST.CUSTOMER ORDER BY :COLUMNNAME :DIRECTION
    

    看,我们可能正在编写一个用户界面,允许用户选择要排序的列以及方向,升序还是降序。

    但是您不能以这种方式使用绑定参数。绑定参数可用于替换 SQL 表达式中的常量值,但不能用于替换表名、列名、ASC/DESC 等 SQL 关键字或其他语法部分。只有常量值,例如带引号的字符串、带引号的日期文字或数字文字。

    那么如何使用绑定参数来保护查询中需要动态的其他部分?

    你不能!

    您的查询的其他部分,例如标识符、SQL 关键字或表达式,必须在您准备查询之前在您的查询字符串中固定。这意味着您不能为它们使用参数占位符。

    有诸如白名单之类的技术可以确保您在 SQL 查询字符串中插入的变量位于一组已知值中,并且有一种标准方法来引用标识符,但这些其他方法与绑定参数不同。

    您可能会喜欢我的演示文稿SQL Injection Myths and Fallacies。这是我将其作为网络研讨会展示的录音:https://www.youtube.com/watch?v=VldxqTejybk

    【讨论】:

    • 虽然这是真实且良好的信息,但我不太确定它与他的具体问题“这怎么可能?”有什么关系。这很好地解释了“当不能我使用参数?”,但这不是被问到的。
    • @Siyual,点了。我在答案的顶部添加了一个介绍段落。这有帮助吗?
    【解决方案4】:

    如果您想疯狂猜测这样的事情是如何可能的,这里有一个:

    • 您使用绑定参数插入到表中
    • DBA 已在该表上创建了插入触发器
    • 该触发器采用插入的值并在execute immediate 中使用它

    ... 或基本上任何其他涉及使用动态 SQL 和由用户提供的数据组成的查询字符串的代码。即使绑定参数也无济于事。

    【讨论】:

    • 由于绑定变量只能用于常量值,您能给出一个代码示例吗?另外,这对 SQL 注入有何影响,因为您提到的过程是预先存在的。
    • 你的意思是如果插入的值本身就是一个完整的SQL语句,然后动态执行?这不是真正的 SQL 注入,如果是这样的话......
    【解决方案5】:

    如果您准备好语句并将所有参数绑定到它,您可以放心,SQL 注入是不可能的。这是因为这种工作方式不会向SQL注入任何东西,所以不可能有SQL注入

    首先编译SQL语句,然后将参数传递给数据库引擎。那时 SQL 文本不再起作用,而是它的编译版本。引擎知道如何处理这两条信息:编译语句和参数。它确实将参数注入到某些 SQL 中,此时它不再起作用:它已经被编译了。

    【讨论】:

      猜你喜欢
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-12
      • 2019-02-27
      • 2021-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多