【问题标题】:JDBC driver escaping arguments for prepared statement?JDBC驱动程序为准备好的语句转义参数?
【发布时间】:2014-03-21 21:17:08
【问题描述】:

来自OWASP page on Preventing SQL Injection in Java

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

我了解准备好的语句如何将用户输入作为参数内容而不是作为 SQL 命令的一部分进行处理。但是我偶然发现了上面引用的句子,我想知道所有的转义是什么。这如何帮助防止注入攻击?

【问题讨论】:

    标签: java jdbc sql-injection


    【解决方案1】:

    假设你的陈述是

    "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 <> '
    

    查询将变为

    select * from foo where name = '' or 1 = 1 or name <> ''
    

    因此查询将加载表的每一行。这就是 SQL 注入的全部意义所在。

    【讨论】:

    • 我的名字是' or 1=1;delete from foo where id&gt;0;select * from foo where name='会更好
    • @vanOekel:但是有没有数据库驱动程序接受一次执行多个语句?
    • 如果你使用准备好的语句则不行,但是如果你懒惰并使用connection.createStatement().execute(query),驱动程序可以允许多条语句(我在单元测试中使用它来一次性插入多条记录)。跨度>
    • 谢谢,我明白什么是 sql 注入 - 但想知道为什么转义会阻止 sql 注入攻击,所以我明白了 - 它没有
    • 确实如此。因为撇号不再被解释为查询的一部分。它们被解释为查询参数值的一部分。简而言之,准备好的语句改为执行以下查询:select * from foo where name = 'O''Reilly'。自己尝试一下,看看会发生什么。
    猜你喜欢
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 2013-07-10
    • 2015-07-14
    • 2014-04-25
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    相关资源
    最近更新 更多