演示JDBC应用编程中的安全问题:
控制台test61,test6输出截图如下:
PreparedStatement和Statement对SQL参数注入攻击的处理:
SQL注入攻击简要介绍:
SQL注入攻击是黑客对数据库进行攻击的常用手段之一,SQL注入即是指web应用程序对用户输入数据的合法性没有判断,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
Statement没有对此做任何校验,需要用户自己额外编写大量检验SQL参数注入的代码,而且还不一定考虑全面,
PreparedStatement采用预编译语句的方式很好的解决了SQL参数注入攻击的问题。
下面通过简单的实例展示:查询用户信息
1.在数据库中创建一张表users_jdbc
-- Create table
create table USERS_JDBC
(
username VARCHAR2(20),
password VARCHAR2(20),
register_time VARCHAR2(10)
)
插入一些数据:
admin manager 2018/02/03
jack 1234 2018/06/05
2.编写测试程序
public class TestDay02 {
/**
* 使用PreparedStatement解决注入攻击
*/
@Test
public void test6(){
//假设用户输入的数据如下
String username = "admin";
String password = "a'or'b'='b";
Connection conn = null;
try {
conn = DBUtil.getConnection();
String sql = "select * from users_jdbc "
+"where username=? "
+"and password=? ";
//System.out.println(sql);
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
while(rs.next()){
System.out.println("登录成功!");
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("查询用户失败!",e);
}finally{
DBUtil.close(conn);
}
}
/**
* Statement:sql注入攻击
*/
@Test
public void test61() {
//假设用户输入的数据如下
String username = "admin";
String password = "a' or 'b'='b";
Connection con = null;
try {
con = DBUtil.getConnection();
String sql = "select * from users_jdbc "
+"where username='"+username+"'"
+" and password='"+password+"'";
System.out.println(sql);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
System.out.println("登录成功.");
System.out.println(rs.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(
"查询用户失败", e);
} finally {
DBUtil.close(con);
}
}
}
分别使用Junit方式运行如上程序【test61,test6】可以看到
PreparedStatement很好的解决了sql注入问题,而Statement则存在sql注入问题,随意访问了数据库数据。

