SQL注入,最简单的解决方案

时间:2009-09-16 02:28:19

标签: sql sql-server oracle tsql plsql

如果我只是用双引号替换所有传入的单引号,我不确定有人会破坏我的SQL。有人可以启发我的Oracle和SQL Server示例吗?感谢。

string sql1 = "select * from users where user_id = '" + "O'Reily".Replace("'", "''").Replace("\", "") + "'";

==> “select * from users userdid ='O''Reily'

string sql2 = "select * from users where user_id = '" + "O'''Reily".Replace("'", "''").Replace("\", "") + "'";

==> “select * from users user_id ='O''''''Reily”

更新:斜杠'\'是应用程序中的受限字符,在查询中使用之前将被删除。双短划线可以很容易地添加到受限字符列表中。

4 个答案:

答案 0 :(得分:16)

参数化您的变量。认真。所有现代环境都有这样的设施,你不必担心转义序列,例如\',它将变成你的方案(在Oracle中)成为转义报价和常规(终止)报价。 / p>

还有很多其他技巧可以解决这个问题,我没有列举,因为它们没有帮助。

再次:参数化您的变量。认真。如果您不了解如何使用参数化,那么成为另一个被黑客入侵的统计信息。

编辑:阅读保罗答案中的链接,这是另一个:http://unixwiz.net/techtips/sql-injection.html

无论你认为你的卫生条件多么聪明,你做错了。 尤其是,如果你必须处理多个后端。

用字符串构建查询是为数不多的事情之一,我会解雇人们......这样的程序员给公司带来的风险大于他们带来的任何其他东西(特别是在我们制作之后)很明显,我们不会在第一天接受这样的代码,并提供一个实体框架,使这些事情变得不必要)。

答案 1 :(得分:4)

为了防止SQL注入,您真正应该做的是使用绑定的位置或命名参数,而不是将SQL构造为内联用户输入的字符串。如何完成取决于您的应用程序如何访问数据库。例如,以下是使用JDBC在Java中的样子:

为:

String updateString = "UPDATE COFFEES SET SALES = 75 " + 
                      "WHERE COF_NAME LIKE 'Colombian'";
stmt.executeUpdate(updateString);

好:

PreparedStatement updateSales = con.prepareStatement(
        "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate():

我从这里借用了这个例子: http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html

答案 2 :(得分:3)

您提出的解决方案很容易包含\'字符串,这会结束您引用的部分并允许注入其他命令。

您希望尽可能使用SQL预处理语句,这些语句应该无处不在。基本上,您使用特定的占位符为您的数据编写sql,然后通过单独的非解释通道将该数据传递给sql server。

一些链接:

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html

http://mattbango.com/notebook/web-development/prepared-statements-in-php-and-mysqli/

答案 3 :(得分:0)

有一些技巧涉及攻击者利用应用程序截断输入:

http://www.rampant-books.com/t_super_sql_154_ideas_prevent_injection.htm