SQl注入的防御
1.使用参数化的过滤性语句
Prepared Statements (Parameterized Queries)
Parameterized queries force the developer to first define all the SQL code, and
then pass in each parameter to the query later. This coding style allows the
database to distinguish between code and data, regardless of what user input is
supplied.
Prepared Statements通过sql逻辑与数据的分离来增加安全,sql逻辑与数据的分离能防止普通类型的sql注入攻击(SQL injection attack),在一些特殊的query中,提交从客户端那接受来的数据时,应该很注意,在使用麻烦字符(如:single quote, double quote, and backslash
characters)时这注意是很有必要的。
参数化查询
近年来,自从参数化查询出现后,SQL注入漏洞已成明日黄花。
参数化查询(Parameterized Query 或
Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值。
在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成SQL指令的编译后,才套用参数运行,因此就算参数中含有指令,也不会被数据库运行。Access、SQL
Server、MySQL、SQLite等常用数据库都支持参数化查询。
要防御SQL注入,用户的输入就绝对不能直接被嵌入到SQL语句中。恰恰相反,用户的输入必须进行过滤,或者使用参数化的语句。参数化的语句使用参数而不是将用户输入嵌入到语句中。在多数情况中,SQL语句就得以修正。然后,用户输入就被限于一个参数。下面是一个使用Java和JDBC API例子:
PreparedStatement prep = conn.prepareStatement("SELECT * FROM USERS WHERE
PASSWORD=?");
prep.setString(1, pwd);
总体上讲,有两种方法可以保证应用程序不易受到SQL注入的攻击,一是使用代码复查,二是强迫使用参数化语句的。强迫使用参数化的语句意味着嵌入用户输入的SQL语句在运行时将被拒绝。不过,目前支持这种特性的并不多。如H2 数据库引擎就支持。
2. 在服务器端对用户输入进行过滤
我们要对一些特殊字符,比如单引号,双引号,分号,逗号,冒号,连接号等进行转换或者过滤;使用强数据类型,比如你需要用户输入一个整数,就要把用户输入的 数据转换成整数形式;限制用户输入的长度等等。这些检查要放在server运行,client提交的任何东西都是不可信的。
3. 详细错误信息不要暴露给用户
因为黑客们可以利用这些消息。错误信息经常会透露一些数据库设计的细节。要使用一种标准的输入确认机制来验证所有的输入数据的长度、类型、语句、企业规则等
4. 存储过程
http://netsecurity.51cto.com/art/201108/287651.htm
SQL注入与防御(很多)
http://sec.chinabyte.com/36/11409036.shtml
SQL注入攻击的种类和防范手段
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet