您的位置:首页 > 博客中心 > 数据库 >

【Java编程】JDBC注入攻击-Statement 与 PreparedStatement

时间:2022-03-10 17:11

在上一篇我们介绍了如何使用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端测试结果:

140514 10:16:13 15 Query SET character_set_results = NULL 15 Query SHOW VARIABLES 15 Query SHOW WARNINGS 15 Query SHOW COLLATION 15 Query SET autocommit=1 15 Query select * 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端测试结果:

140514 10:23:14 16 Connect root@localhost on db_bbs 16 Query SET NAMES latin1 16 Query SET character_set_results = NULL 16 Query SHOW VARIABLES 16 Query SHOW WARNINGS 16 Query SHOW COLLATION 16 Query SET autocommit=1 16 Query select * 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端测试结果:

140514 10:37:04 17 Connect root@localhost on db_bbs 17 Query SET NAMES latin1 17 Query SET character_set_results = NULL 17 Query SHOW VARIABLES 17 Query SHOW WARNINGS 17 Query SHOW COLLATION 17 Query SET autocommit=1 17 Prepare select * from user where username = ? and password = ? 17 Execute select * 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 Query	SET character_set_results = NULL
		   19 Query	SHOW VARIABLES
		   19 Query	SHOW WARNINGS
		   19 Query	SHOW COLLATION
		   19 Query	SET autocommit=1
		   19 Prepare	select * from user where username = ? and password = ?
		   19 Execute	select * 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‘

【参考】

(推荐)

【你可能感兴趣】

转载请注明出处:,谢谢!

【Java编程】JDBC注入攻击-Statement 与 PreparedStatement,布布扣,bubuko.com

热门排行

今日推荐

热门手游