如果我只是用双引号替换所有传入的单引号,我不确定有人会破坏我的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”
更新:斜杠'\'是应用程序中的受限字符,在查询中使用之前将被删除。双短划线可以很容易地添加到受限字符列表中。
答案 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