【Java编程】JDBC注入攻击

【Java编程】建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement我们介绍了如何使用JDBC驱动建立一个简单的连接,并实现使用Statement和PreparedStatement进行数据库查询,本篇blog将接着上篇blog通过SQL注入攻击比较Statement和PreparedStatement。当然这两者还有很多其他方面的不同,在之后的blog中会继续更新。

【Statement查询】

1、在DBHelper.java中新增一个通过username和password查询user的方法。

public static void queryByUser(String username,String password) {Connection conn = DBConnection.getConnection();Statement stmt = null;ResultSet rs = null;try {stmt = conn.createStatement();rs = stmt.executeQuery("select * from user where username = '" + username+"' and password='"+password+"'");while (rs.next()) {User user = new User();user.setId(rs.getInt("id"));user.setUsername(rs.getString("username"));user.setPassword(rs.getString("password"));user.setGender(rs.getBoolean("gender"));user.setRegtime(rs.getDate("regtime"));System.out.println(user.toString());}} catch (SQLException e) {e.printStackTrace();}finally {DBConnection.closeResultSet(rs);DBConnection.closeStatement(stmt);DBConnection.closeConnection(conn);}}

2、在DBHelperTest.java中新增一个测试方法进行测试

public void queryByUserTest(){DBHelper.queryByUser("jack", "jack");}

Java端测试结果:

User [id=2, username=jack, password=jack, gender=true, regtime=2014-05-14]

测试结果表明:通过一个有效的用户名和密码,成功获取到了该用户的所有信息。

3、 通过MySQL日志信息,跟踪查询sql语句。具体方法参考 MySQL如何跟踪sql语句。

打开mysql.log日志,跟踪查看最新的日志,如下所示:

140514 10:16:13   15 QuerySET character_set_results = NULL   15 QuerySHOW VARIABLES   15 QuerySHOW WARNINGS   15 QuerySHOW COLLATION   15 QuerySET autocommit=1   15 Queryselect * from user where username = 'jack' and password='jack'   15 Quit

日志信息表明:数据库端执行了正常的查询语句。

4、在DBHelperTest.java中新增一个注入攻击测试,用户名输入:hack(任意字符串),密码输入:’ or ‘1’=’1

public void queryByUserInjectTest(){DBHelper.queryByUser("hack", "' or '1'='1");}

Java端测试结果:

User [id=1, username=andy, password=andy, gender=true, regtime=2014-05-13]User [id=2, username=jack, password=jack, gender=true, regtime=2014-05-14]User [id=3, username=rose, password=rose, gender=false, regtime=2014-05-13]

测试结果表明:通过注入攻击,一个非法的用户可以获取到user表中的所有用户信息,太可怕了!

5、通过MySQL日志信息,跟踪查询sql语句,分析数据端到底发生了什么事情。

140514 10:23:14   16 Connectroot@localhost on db_bbs   16 QuerySET NAMES latin1   16 QuerySET character_set_results = NULL   16 QuerySHOW VARIABLES   16 QuerySHOW WARNINGS   16 QuerySHOW COLLATION   16 QuerySET autocommit=1   16 Queryselect * from user where username = 'hack' and password='' or '1'='1'   16 Quit

数据库端执行了一条语句:

select * from user where username = ‘hack’ and password=” or ‘1’=’1′

因为where条件恒为真,相当于执行了:

select * from user

通过这条语句获取到了所有的用户信息。

【PreparedStatement查询】1、在DBHelper.java中新增一个通过username和password查询user的方法。

public static void queryPrepareByUser(String username,String password) {Connection conn = DBConnection.getConnection();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement("select * from user where username = ? and password = ?");ps.setString(1,username);// 设置占位符参数ps.setString(2, password);rs = ps.executeQuery();while (rs.next()) {User user = new User();user.setId(rs.getInt("id"));user.setUsername(rs.getString("username"));user.setPassword(rs.getString("password"));user.setGender(rs.getBoolean("gender"));user.setRegtime(rs.getDate("regtime"));System.out.println(user.toString());}} catch (SQLException e) {e.printStackTrace();} finally {DBConnection.closeResultSet(rs);DBConnection.closeStatement(ps);DBConnection.closeConnection(conn);}}

2、在DBHelperTest.java中新增一个测试方法进行测试

public void queryByPreparedUserTest(){DBHelper.queryPrepareByUser("jack", "jack");}

Java端测试结果:User [id=2, username=jack, password=jack, gender=true, regtime=2014-05-14]

测试结果表明:通过一个合法的用户名和密码,得到了该用户的所有信息。

3、通过MySQL日志信息,跟踪查询sql语句。

140514 10:37:04   17 Connectroot@localhost on db_bbs   17 QuerySET NAMES latin1   17 QuerySET character_set_results = NULL   17 QuerySHOW VARIABLES   17 QuerySHOW WARNINGS   17 QuerySHOW COLLATION   17 QuerySET autocommit=1   17 Prepareselect * from user where username = ? and password = ?   17 Executeselect * from user where username = 'jack' and password = 'jack'   17 Close stmt   17 Quit

日志信息表明:数据库端首先执行了预编译,并执行了正常的查询语句。

4、在DBHelperTest.java中新增一个注入攻击测试:

public void queryByPreparedUserInjectTest(){DBHelper.queryPrepareByUser("hack", "' or '1'='1");}

Java端测试结果:

没有打印出任何消息,即没有获取到用户的信息,难道注入攻击无效!

5、通过MySQL日志信息,跟踪查询sql语句,为什么注入攻击无效了?

140514 10:42:42   19 QuerySET character_set_results = NULL   19 QuerySHOW VARIABLES   19 QuerySHOW WARNINGS   19 QuerySHOW COLLATION   19 QuerySET autocommit=1   19 Prepareselect * from user where username = ? and password = ?   19 Executeselect * from user where username = 'hack' and password = '\' or '1\'='1'   19 Close stmt   19 Quit

原来是执行了:select * from user where username = ‘hack’ and password = ‘\’ or ‘1\’=’1’

【参考】

JDBC Statement vs PreparedStatement – SQL Injection Example(推荐)

JDBC为什么要使用PreparedStatement而不是Statement

【你可能感兴趣】

建立一个简单的JDBC连接-Drivers, Connection, Statement and PreparedStatement

http://blog.csdn.net/andie_guo/article/details/25775163,谢谢!

没有什么可凭仗,只有他的好身体,没有地方可去,

【Java编程】JDBC注入攻击

相关文章:

你感兴趣的文章:

标签云: