关于防止SQL注入的理解,提高系统安全性(学以致用)

这篇文章讲述的是关于SQL注入的问题,防止非法进入系统,提高系统安全性。

在开发项目的过程中,登录是几乎所有的系统都必须具备的功能,但是有的系统在开发的时候可能就没有注意到SQL注入的情况,导致用户非法登录系统。为了让用户登录确保都是系统的合法用户,那么就得防止非法用户进行SQL注入进入系统。

下面先来看一下下面这样两种登录系统的方式吧:

方式一:

登录查询数据库java代码:

/**
	 * 通过用户代码和密码查询数据库进行判断是否登录成功
	 * @param userId
	 * @param password
	 * @return
	 */
	public boolean login(String userId,String password){
		boolean flag = false; 
		String sql = "select * from t_user where user_id='"+userId+"' and password='" + password+"'"; 
		System.out.println(sql);
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			conn = DbUtil.getConnection();
			stmt = conn.createStatement(); 
			rs = stmt.executeQuery(sql);
			if (rs.next()) { 
				flag = true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally { 
			DbUtil.close(stmt);// 关闭prepareStatementd对象
			DbUtil.close(conn);// 关闭数据库连接
		}
		return flag;
	}
登录端的jsp页面中的java代码如下:

String command = request.getParameter("command");
	if ("login".equals(command)) {
		String userId = request.getParameter("userId");
		String password = request.getParameter("password"); 
	
		//演示SQL注入----begin
		boolean success = UserManager.getInstance().login(userId, password);
		if (success) {
			response.sendRedirect(request.getContextPath() + "/main.jsp");
		}
		//演示SQL注入----end	
	}
方式二:
/**
	 * 先通过用户代码查出用户信息,然后判断密码是否正确 
	 * @param userId
	 * @param password
	 * @return
	 */  
 	public User login(String userId,String password){
		User user = findUserById(userId); 
		if(user==null){
			throw new UserNotFoundException("用户代码不存在");//这是自定义的异常类,继承了RuntimeException
		}
		if(!user.getPassword().equals(password)){
			throw new PasswordNotCorrectException("用户名或密码不正确");//这是自定义的异常类,继承了RuntimeException
		}
		return user;
	}
/**
     * 根据用户ID查找用户
     * 
     * @param userId
     * @return
     */
    public User findUserById(String userId) {
        User user = null;
        String sql = "select user_name,password,contact_tel,email,create_date from t_user where user_id=?";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DbUtil.getConnection();
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, userId);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                user = new User();
                user.setUserId(userId);
                user.setUserName(rs.getString(1));
                user.setPassword(rs.getString(2));
                user.setContactTel(rs.getString(3));
                user.setEmail(rs.getString(4));
                user.setCreateDate(rs.getTimestamp(5));
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            DbUtil.close(conn);// 关闭数据库连接
            DbUtil.close(pstmt);// 关闭prepareStatementd对象
        }
        return user;
    }

登录端的jsp页面中的java代码如下:
String command = request.getParameter("command");
	if ("login".equals(command)) {
		String userId = request.getParameter("userId");
		String password = request.getParameter("password");

		try {
			User user = UserManager.getInstance().login(userId, password);			 
			//将用户信息设置到session中
			session.setAttribute("user_info", user);	 		
			//重定向到主控页面
			response.sendRedirect(request.getContextPath() + "/main.jsp");
		}catch(UserNotFoundException e) {
			out.println("<script>alert('"+e.getMessage()+"')</script>");
		}catch(PasswordNotCorrectException e) {
			out.println("<script>alert('"+e.getMessage()+"')</script>");
		}
       }

上面分别使用了两种方式来进行登录操作,登录其实就是查询数据库中的用户信息,并进行用户合法性的验证,两种方式按照正常的方式都能登录(即用户有合法的用户代码和密码)。但是对于第一种情况的的话,用户可以不是用合法的用户信息就能进行登录,也就是说用户可以进行SQL的注入使其达到登录系统的目的。

谈到SQL注入,那是怎样的一个注入法呢?

对于第一种情况,不管是对用户代码还是密码,可以写这样的语句进行登录,比如密码吧,随便乱写一个用户名 ,然后写下面这样的SQL语句作为密码,然后进行登录:

比如:用户代码为:yyyyy,用做密码的SQL语句:

1' OR '1'='1

此时查询数据库的SQL语句实际上为:

select * from t_user where user_id='yyyyy' and password='1' OR '1'='1'

使用该语句查询数据库,肯定是可以查询到结果的,如果判断不合理的话就会出现安全性问题,上面的第一种实现方式如果使用刚才的SQL注入就会随意的登录系统,导致不安全的问题产生。

所以在编写用户登录的时候需要注意防止SQL注入的情况,你注意到了吗?如果没有就好好看一下吧。




  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值