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

Fea*_*ure 5 sql oracle sql-injection

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

我的DBA说使用绑定变量并不能完全保护SQL注入,但我无法弄清楚这是怎么回事,因为绑定变量尤其是字符串通常会强制注入的SQL成为WHERE子句中的字符串.

例:

SELECT CUST_ID  
FROM CUST.CUSTOMER 
WHERE FIRST_NAME=:FNAME;
Run Code Online (Sandbox Code Playgroud)

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

SELECT CUST_ID 
FROM CUST.CUSTOMER 
WHERE FIRST_NAME="SELECT FNMAME WHERE CUST_ID=10040";
Run Code Online (Sandbox Code Playgroud)

这将返回0行.

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

再次感谢.

tri*_*cot 8

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

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


Bil*_*win 5

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

考虑这个查询:

SELECT CUST_ID FROM CUST.CUSTOMER ORDER BY :COLUMNNAME :DIRECTION
Run Code Online (Sandbox Code Playgroud)

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

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

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

你不能!

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

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

您可能会喜欢我的演讲《SQL 注入神话和谬误》。以下是我将其作为网络研讨会进行演示的录音:https://www.youtube.com/watch?v=VldxqTejybk

  • 虽然这是真实且良好的信息,但我不太确定它与他的具体问题“这怎么可能?”有何关系。这很好地解释了“什么时候我不能使用参数?”,但这不是问题所在。 (4认同)

Mar*_*ber 0

严格来说,使用绑定变量时确实可能发生SQL 注入。下面的查询使用 BV ,如果参数被操纵,可能会成为SQL 注入的对象column_list

 'select' + column_list + ' from T where col :1'
Run Code Online (Sandbox Code Playgroud)

因此,缺少的是在静态查询中使用绑定变量 ,并避免使用参数(例如列列表)进行语句连接。