SQL注入:
什么是SQL注入?
使用Statement实例化对象获取执行SQL语句对象的时候,会产生一个SQL注入的问题.因为是先将SQL语句编译成字符串的形式,然后再连接到MySQL中去执行,所以会产生这个问题.
例如:进行用户名密码登录的时候的SQL语句为:
select count(*) from user where username='用户输入数据' and password='用户输入数据';
此时,如果用户在输入密码password的时候输入
' or '1'='1
此时,该语句在执行的时候会将用户输入的内容先编译成SQL语句,然后再执行,SQL语句会变成
select count(*) from user where username='用户输入数据' and password='' or '1'='1';
此处 password='' or '1'='1';这两个条件满足一个就是真的条件,SQL语句就不会判断密码是否正确,只要用户名正确,那么就能登录成功,这就是SQL注入问题.
即,在本应该传值的地方输入了一条SQL语句,使得原来SQL语句的逻辑判断失去了作用,就会产生很严重的后果.入侵者可以通过登录后台系统来修改网站的数据,使得网站被攻击
如何解决SQL注入问题?
需要在编译的过程中将传值的地方占住,用户输入的数据只是作为一个值来传递给原来占位的地方,即预编译.
使用PreparedStatement实例化对象
//预先编译好SQL语句,将用户输入部分用?占住,这样编译之后这两个部分就锁死了,逻辑代码已经形成
String sql = "select count(*) from user where username=? and password=?";
PreparedStatement ps = conn.preparedStatement(sql);
//获取用户输入的信息的时候,作为值传递给上述两个?,传递进去的是两个字符串
ps.setString(1,用户输入的数据--用户名);//1和2表示的是上面两个问号的位置
ps.setString(2,用户输入的数据--密码);
//执行SQL语句,进行相应的业务功能
ResultSet rs = ps.executeQuery();
这样可以在编译的时候得到用户输入的两个值,就算用户输入了上述的那种SQL语句,也只是作为一个值传递进SQL语句,SQL语句已经预先编译好了,锁死了,用户输入的内容不会影响SQL语句的逻辑代码部分,从而解决了SQL注入问题