zoukankan      html  css  js  c++  java
  • 著名的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

  • 相关阅读:
    POJ 1681 Painter's Problem(高斯消元法)
    HDU 3530 Subsequence(单调队列)
    HDU 4302 Holedox Eating(优先队列或者线段树)
    POJ 2947 Widget Factory(高斯消元法,解模线性方程组)
    HDU 3635 Dragon Balls(并查集)
    HDU 4301 Divide Chocolate(找规律,DP)
    POJ 1753 Flip Game(高斯消元)
    POJ 3185 The Water Bowls(高斯消元)
    克琳:http://liyu.eu5.org
    WinDbg使用
  • 原文地址:https://www.cnblogs.com/GuoXueLi/p/mysql.html
Copyright © 2011-2022 走看看