使用绑定变量时 SQL 注入是如何实现的?
How is SQL Injection Possible When Using Bind Variables?
如何在使用绑定变量时进行 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";
这将 return 0 行。
我在 Internet 上搜索了这个问题的答案,甚至搜索了这个网站,但我找不到。
再次感谢。
查询参数不可能 "break" 并允许 SQL 在参数化查询中注入。但参数绑定确实没有为所有可能的动态查询提供解决方案。也许这就是您的 DBA 的意思(您为什么不问她?)。
考虑这个查询:
SELECT CUST_ID FROM CUST.CUSTOMER ORDER BY :COLUMNNAME :DIRECTION
看,我们可能正在编写一个用户界面,允许用户选择排序的列和方向,升序还是降序。
但是你不能这样使用绑定参数。绑定参数可用于替换 SQL 表达式中的常量值,但不能替换 table 名称、列名、SQL 关键字,如 ASC
/DESC
, 或语法的其他部分。仅常量值,例如带引号的字符串、带引号的日期文字或数字文字。
那么如何使用绑定参数来保护需要动态查询的其他部分?
你不能!
查询的其他部分,例如标识符、SQL 关键字或表达式,必须在您准备查询之前固定在查询字符串中。这意味着您不能为它们使用参数占位符。
有白名单等技术可以确保您在 SQL 查询字符串中插入的变量在一组已知值中,并且有一种引用标识符的标准方法,但其他方法不是与绑定参数相同。
你可能会喜欢我的介绍SQL Injection Myths and Fallacies. Here's a recording of me presenting it as a webinar: https://www.youtube.com/watch?v=VldxqTejybk
您可以放心,如果您准备语句并将所有参数绑定到它,SQL 注入是不可能的。这是因为这种工作方式不会向SQL注入任何东西,所以不可能有SQL注入 ].
首先编译SQL语句,然后将参数传递给数据库引擎。那时 SQL 文本不再起作用,而是它的编译版本。引擎知道如何处理这两条信息:编译语句和参数。它 不 将参数注入一些 SQL,这在那时不再起作用:它已经被编译了。
如果您想对这样的事情怎么可能进行疯狂的猜测,这里有一个:
- 您插入 table,使用绑定参数
- DBA 已经在 table
上创建了一个插入触发器
- 该触发器获取插入的值并将其用于
execute immediate
... 或基本上涉及使用动态 SQL 以及由用户提供的数据组成的查询字符串的任何其他代码。即使是绑定参数也帮不了你。
说到常规查询,two known edge cases Mysql/PDO 都与 Oracle 无关。
说到存储过程,存储过程本身当然有 ,但我认为这要么是无关紧要的情况,要么是预处理语句的使用不一致.
所以您的 DBA 很可能只是在某个地方听到了一些谣言,但不太清楚他在说什么。
严格来说SQL注入在使用绑定变量时确实是可能的。下面的查询 use BV and can be subject of SQL injection 以防参数 column_list
被操纵。
'select' + column_list + ' from T where col :1'
所以缺少的是在静态查询中使用绑定变量 并避免使用参数 的语句连接,例如对于列列表。
如何在使用绑定变量时进行 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";
这将 return 0 行。
我在 Internet 上搜索了这个问题的答案,甚至搜索了这个网站,但我找不到。
再次感谢。
查询参数不可能 "break" 并允许 SQL 在参数化查询中注入。但参数绑定确实没有为所有可能的动态查询提供解决方案。也许这就是您的 DBA 的意思(您为什么不问她?)。
考虑这个查询:
SELECT CUST_ID FROM CUST.CUSTOMER ORDER BY :COLUMNNAME :DIRECTION
看,我们可能正在编写一个用户界面,允许用户选择排序的列和方向,升序还是降序。
但是你不能这样使用绑定参数。绑定参数可用于替换 SQL 表达式中的常量值,但不能替换 table 名称、列名、SQL 关键字,如 ASC
/DESC
, 或语法的其他部分。仅常量值,例如带引号的字符串、带引号的日期文字或数字文字。
那么如何使用绑定参数来保护需要动态查询的其他部分?
你不能!
查询的其他部分,例如标识符、SQL 关键字或表达式,必须在您准备查询之前固定在查询字符串中。这意味着您不能为它们使用参数占位符。
有白名单等技术可以确保您在 SQL 查询字符串中插入的变量在一组已知值中,并且有一种引用标识符的标准方法,但其他方法不是与绑定参数相同。
你可能会喜欢我的介绍SQL Injection Myths and Fallacies. Here's a recording of me presenting it as a webinar: https://www.youtube.com/watch?v=VldxqTejybk
您可以放心,如果您准备语句并将所有参数绑定到它,SQL 注入是不可能的。这是因为这种工作方式不会向SQL注入任何东西,所以不可能有SQL注入 ].
首先编译SQL语句,然后将参数传递给数据库引擎。那时 SQL 文本不再起作用,而是它的编译版本。引擎知道如何处理这两条信息:编译语句和参数。它 不 将参数注入一些 SQL,这在那时不再起作用:它已经被编译了。
如果您想对这样的事情怎么可能进行疯狂的猜测,这里有一个:
- 您插入 table,使用绑定参数
- DBA 已经在 table 上创建了一个插入触发器
- 该触发器获取插入的值并将其用于
execute immediate
... 或基本上涉及使用动态 SQL 以及由用户提供的数据组成的查询字符串的任何其他代码。即使是绑定参数也帮不了你。
说到常规查询,two known edge cases Mysql/PDO 都与 Oracle 无关。
说到存储过程,存储过程本身当然有
所以您的 DBA 很可能只是在某个地方听到了一些谣言,但不太清楚他在说什么。
严格来说SQL注入在使用绑定变量时确实是可能的。下面的查询 use BV and can be subject of SQL injection 以防参数 column_list
被操纵。
'select' + column_list + ' from T where col :1'
所以缺少的是在静态查询中使用绑定变量 并避免使用参数 的语句连接,例如对于列列表。