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

  • 相关阅读:
    velocity masterplate 第一个程序的运行
    java 关于集合框架
    java 关于>>>位运算
    QCA wifi驱动强制为HT40
    Linux内核调试方法的总结(转载)
    移动端利用webkitbox水平垂直居中
    Under Construction to Beta
    网站自动备份
    writely 邀请?
    Google Carlendar coming ?
  • 原文地址:https://www.cnblogs.com/GuoXueLi/p/mysql.html
Copyright © 2011-2022 走看看