著名的sql注入问题-问题的原因分析及总结

Statement安全漏洞(sql注入问题)
问题展示:

首先我的Mysql数据库中有一张users表,如下图所示

	/**
	 * 根据用户名查询用户
	 * @param username 需要查询的用户名
	 * @return User 记录对应的JavaBean对象
	 */
	public static User find(String name){
		Connection conn = null;
		Statement sta = null;
		ResultSet re = null;
		User user = null;
		try{
			//获取JavaApp与Mysql数据的连接
			conn = JDBCUtils.getConnection();
			//创建封装SQL语句的对象
			sta = conn.createStatement();
			//执行sql语句返回结果集合'or true or'
			String sql = "select id,username,password,email,Date from users where username='"+ name + "'";
			re = sta.executeQuery(sql);
			while(re.next()){
				int id = re.getInt("id");
				String username = re.getString("username");
				String password = re.getString("password");
				String email = re.getString("email");
				Date d = re.getDate("Date");
				user = new User(id,username,password,email,d);
			}
			
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("根据用户名查询失败");
		}finally{
			JDBCUtils.close(re);
			JDBCUtils.close(sta);
			JDBCUtils.close(conn);
		}
		return user;
	}
	
	public static void main(String[] args) {
          //我们查找的是表中已有的数据李四 User user = Demo2_find.find("李四"); System.out.println(user == null ? "查无此人" : "查有此人"); }

  运行上面这段代码,程序返回的结果是李四在Mysql数据库确实存在,为了验证测试效果,

这一次,我将上图中标红的部分User user = Demo2_find.find("李四");改为查找王五这个人,大家都知道王五这个人在数据库是不存在的.这次运行的结果为进一步证明,上面的代码是没有问题的,这是我依旧将标红部分的代码改掉,改成User user = Demo2_find.find("'or true or'");这时会发生什么神奇的效果呢?我们运行代码看一下.

为了让大家看的清楚一点,我将整张屏幕截取了下来

我们可以发现,当我们输入'or true or'进行查询的时候竟然通过了,能够查询到Mysql中的数据.

这就是著名的sql注入问题.

 产生原因:

  因为SQL语句拼接,传入了SQL语句的关键字,绕过了安全检查.
客户端利用JDBC-【Statement】的缺点,传入非法的参数,从而让JDBC返回不合法的值,我们将这种情况下,统称为SQL注入。
解决方案:
  使用PreparedStatement对象就可以解决。PreparedStatement对象预处理对象。允许使用占位符对SQL语句中的变量进行占位。对SQL语句进行预先编译。传入SQL语句的关键字,不会被当成关键字而是普通的字符串。包括:程序执行时动态为?符号设置值,安全检查,避免SQL注入问题,预处理能力

 

select * from user where username = ? and password = ?

Statement与PreparedStatement的区别
  现在项目中都不直接用Statement了,而用PreparedStatement。
PreparedStatement它除了具有Statement是所有功能外,
还有动态SQL处理能力,包括:程序执行时动态为?符号设置值,安全检查,避免SQL注入问题,预处理能力。

Statement只能处理静态SQL
  1,PreparedStatement既能处理静态SQL,又能处理动态SQL,它继承了Statement的特点
  2,站在预处理这个角度来说的:
  PreparedStatement【适合】做连续多次相同结构的SQL语句,有优势。
  Statement【适合】做连续多次不相同结构的SQL语句,有优势。
  适合:是只效率会更高,但并不表示一定要这才样
  3,PreparedStatement
  1_支持动态SQL,也支持静态SQL
  2_预处理
---相同结构的SQL
  select id,name from users where id = 1
  select id,name,gender from users where id = 2;
 是不相同结构
---不同结构的SQL
声明:
  静态SQL也可以用PreparedStatement
适合:
  静态SQL---优先Statement

posted on 2016-12-02 11:33  GuoXueLi  阅读(2125)  评论(0编辑  收藏  举报