使用绑定变量时SQL注入是如何实现的?

时间:2017-04-05 15:06:39

标签: sql oracle sql-injection

使用绑定变量时,如何进行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行。

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

再次感谢。

5 个答案:

答案 0 :(得分:4)

查询参数不可能" break"并在参数化查询中允许SQL注入。但是,参数绑定不能为所有可能的动态查询提供解决方案。也许那就是你的DBA意味着什么(为什么不问她?)。

考虑这个问题:

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

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

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

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

你不能!

在准备查询之前,必须在查询字符串中修复查询的其他部分,如标识符,SQL关键字或表达式。这意味着您无法使用参数占位符。

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

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

答案 1 :(得分:3)

如果您准备语句并将所有参数绑定到它,则可以确保无法进行SQL注入。这是因为这种工作方式没有向SQL中注入任何东西,所以不可能有 SQL注入

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

答案 2 :(得分:1)

说到常规查询, Mysql / PDO two known edge cases与Oracle无关。

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

所以你的DBA很可能只是在某个地方听到了一些谣言,但对他所谈论的内容并不了解。

答案 3 :(得分:1)

严格来说,使用绑定变量时确实可以使用 SQL注入使用 BV 下方的查询可以 SQL注入

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

所以缺少的是在静态查询中使用绑定变量

答案 4 :(得分:-3)

如果你想对如何做到这一点有一个疯狂的推测,那就是:

  • 使用绑定参数
  • 插入表中
  • DBA在该表上创建了一个插入触发器
  • 该触发器获取插入的值并在execute immediate
  • 中使用它

...或基本上任何其他涉及将动态SQL与由用户提供的数据组成的查询字符串一起使用的代码。即使绑定参数也无法帮助你。