Java 准备语句的JDBC驱动程序转义参数?

Java 准备语句的JDBC驱动程序转义参数?,java,jdbc,sql-injection,Java,Jdbc,Sql Injection,从: 作为参数传递给准备语句的变量将由JDBC驱动程序自动转义 我理解准备好的语句如何将用户输入分离,作为参数内容处理,而不是作为SQL命令的一部分处理。但我无意中发现了上面引用的句子,我想知道这些逃避是怎么回事。这有助于防止注入攻击吗?假设您的陈述是 "select * from foo where name = '" + name + "'"; 现在,如果name变量恰好是O'Reilly,那么您将得到以下SQL查询,这是无效的: select * from foo where name

从:

作为参数传递给准备语句的变量将由JDBC驱动程序自动转义


我理解准备好的语句如何将用户输入分离,作为参数内容处理,而不是作为SQL命令的一部分处理。但我无意中发现了上面引用的句子,我想知道这些逃避是怎么回事。这有助于防止注入攻击吗?

假设您的陈述是

"select * from foo where name = '" + name + "'";
现在,如果name变量恰好是O'Reilly,那么您将得到以下SQL查询,这是无效的:

select * from foo where name = 'O'Reilly'
改为使用准备好的语句:

"select * from foo where name = ?"
然后,驱动程序将参数正确绑定为字符串,并且O'Reilly中的单引号不会被解释为从
'O
开始的字符串的结尾

在这种简单的情况下,不使用预先准备好的语句将“仅”导致应用程序出现异常。但是如果有人用这样的名字

' or 1 = 1 or name <> '
'或1=1或名称'
查询将变为

select * from foo where name = '' or 1 = 1 or name <> ''
从foo中选择*,其中name=''或1=1或name''

因此,查询将加载表中的每一行。这就是SQL注入的全部内容。

当我的名字是
”或1=1时,它会变得更好;从id>0的foo中删除;选择*from foo where name='
@vanOekel:但是否有任何数据库驱动程序接受一次执行多个语句?不是在使用准备好的语句时,而是在您懒惰且使用
connection.createStatement()。执行(查询)
驱动程序可以允许多个语句(我在单元测试中使用它一次性插入多个记录)。谢谢,我理解sql注入是什么-但我想知道为什么转义可以防止sql注入攻击,所以我明白了-它确实可以。因为撇号不再被解释为查询的一部分。它们被解释为查询参数值的一部分。简言之,prepared语句执行以下查询取而代之的是:
从foo中选择*,其中name='O''Reilly'
。自己试试,看看会发生什么。