在上一篇【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]

測试结果表明:通过一个有效的username和password,成功获取到了该用户的全部信息。

3、 通过MySQL日志信息,跟踪查询sql语句。详细方法參考MySQL怎样跟踪sql语句

打开mysql.log日志。跟踪查看最新的日志。例如以下所看到的:

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中新增一个注入攻击測试,username输入:hack(随意字符串),password输入:' 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 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端測试结果:

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

測试结果表明:通过一个合法的username和password。得到了该用户的全部信息。

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

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'

【參考】

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注入攻击-Statement 与 PreparedStatement的更多相关文章

  1. JDBC中的Statement和PreparedStatement的区别

    JDBC中的Statement和PreparedStatement的区别  

  2. php安全编程—sql注入攻击

    php安全编程--sql注入攻击 定义 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因 ...

  3. 使用JDBC分别利用Statement和PreparedStatement来对MySQL数据库进行简单的增删改查以及SQL注入的原理

    一.MySQL数据库的下载及安装 https://www.mysql.com/ 点击DOWNLOADS,拉到页面底部,找到MySQL Community(GPL)Downloads,点击 选择下图中的 ...

  4. JDBC中的Statement和PreparedStatement的差别

    以Oracle为例吧 Statement为一条Sql语句生成运行计划, 假设要运行两条sql语句 select colume from table where colume=1; select col ...

  5. [转] JDBC中的Statement和PreparedStatement的区别

    以Oracle为例吧 Statement为一条Sql语句生成执行计划,如果要执行两条sql语句select colume from table where colume=1;select colume ...

  6. JDBC中的Statement 和PreparedStatement的区别?

    PreparedStatement是预编译的SQL语句,效率高于Statement. PreparedStatement支持操作符,相对于Statement更加灵活. PreparedStatemen ...

  7. JDBC预编译statement(preparedstatement)和statement的比较、execute与executeUpdate的区别

    和 Statement一样,PreparedStatement也是用来执行sql语句的与创建Statement不同的是,需要根据sql语句创建PreparedStatement除此之外,还能够通过设置 ...

  8. Java学习笔记47(JDBC、SQL注入攻击原理以及解决)

    JDBC:java的数据库连接 JDBC本质是一套API,由开发公司定义的类和接口 这里使用mysql驱动,是一套类库,实现了接口 驱动程序类库,实现接口重写方法,由驱动程序操作数据库 JDBC操作步 ...

  9. jdbc之防sql注入攻击

    1.SQL注入攻击:    由于dao中执行的SQL语句是拼接出来的,其中有一部分内容是由用户从客户端传入,所以当用户传入的数据中包含sql关键字时,就有可能通过这些关键字改变sql语句的语义,从而执 ...

随机推荐

  1. Wordpress 文章添加副标题

    后台编辑区添加自定义副标题字段 /** * Add Subtitle in all post */ function article_subtitle( $post ) { if ( ! in_arr ...

  2. Postgresql 查看建表语句 命令

    pg_dump -U username databasename -W -s -t tablename -s, --schema-only 只转储模式, 不包括数据 -t, --table=TABLE ...

  3. 删除 node 【笔记】

    sudo npm uninstall npm -g sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receip ...

  4. ValueStack、ActionContext

    笔者不知道该用哪个词来形容ValueStack.ActionContext等可以在Struts2中用来存放数据的类.这些类使用的范围不同,得到的方法也不同,下面就来一一介绍. 1. ValueStac ...

  5. 软工实践第八次作业——UML设计

    本次作业博客 团队组成 临时组长:何裕捷 组员:蔡子阳,陈德斌,胡青元,李麒,高裕翔,王焕仁,黄培鑫 UML 用例图 描述的部分: 1 这里是用户个人管理系统的用例图 面临的问题: 1 面临用户登录注 ...

  6. JS获取屏幕宽度

    document.write("屏幕分辨率为:"+screen.width+"*"+screen.height+"<br />" ...

  7. 声卡(Sound Card)基本概念

    声卡 (Sound Card)是实现声音的模拟/数字信号相互转换.信号处理的一种硬件. 声卡的基本功能是把来自话筒.磁带.光盘的原始声音信号加以转换(模数转换或者数模转换),输出到耳机.扬声器.扩音机 ...

  8. hdu 3721 树的直径

    思路:枚举+树的直径 #include<iostream> #include<cstring> #include<cstdio> #include<algor ...

  9. 从jekyll转向hexo

    当年选择jekyll是因为看中了HCZ Material theme这个主题,折腾了很久才把博客搭建好,后来周边人准备些博客的时候已经不推荐使用jekyll了,推荐hexo给好几个人,不用他们折腾,( ...

  10. 【08】Vue 之 vue-cli

    8.1. 前置知识学习 npm 学习 官方文档 推荐资料 npm入门 npm介绍 需要了解的知识点 package.json 文件相关配置选项 npm 本地安装.全局安装.本地开发安装等区别及相关命令 ...