什么是SQL注入?
所谓SQL注入(sql inject),就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
SQL注入产生的原因
平台层注入
由不安全的数据库配置或数据库平台的漏洞所致。
代码层注入
由于程序员对输入未进行细致地过滤,从而执行了非法的数据查询。
其他原因:不当的类型处理、不安全的数据库配置、不合理的查询集处理、不当的错误处理、转义字符处理不合适、多个提交处理不当。
SQL注入例子
String sql = "SELECT USERNAME,PASSWORD FROM USER WHERE USERNAME='" + username + "' AND PASSWORD='" + password + "'";
上面这个SQL语句就存在安全漏洞。
假如user表中有用户名为zrx,密码为zrx的记录,而在前台页面提交表单的时候用户输入的用户名和密码是随便输入的,这样当然是不能登录成功的。
但是如果后台处理的sql语句是如上所写,前台页面用户名也是随便输入,密码是形如这样的aaa' or '1'='1
(aaa也可以随便代替),处理登录的SQL语句就相当于是这样的:
SELECT USERNAME,PASSWORD FROM USER WHERE USERNAME='zrx' AND PASSWORD='aaa' or '1'='1';
我们知道,1=1是true,所以上面这个SQL语句是可以执行成功的,这是一个SQL注入问题。
解决
利用PreparedStatement先预编译对象,它是Statement的子类。
特点:性能高;预先编译好sql语句;sql语句中的参数会发生变化,过滤掉用户输入的关键字。
部分代码举例:
Connection conn = DriverManager.getConnection(url,user,password);
String sql = "SELECT * FROM USER WHERE USERNAME=? AND PASSWORD=?";
Statement stmt = conn.prepareStatement(sql);
// 给?赋值.
stmt.setString(1,"zrx");//第1个?赋值zrx.
stmt.setString(2,"zrx");//第2个?赋值zrx.