这篇文章讲述的是关于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注入的情况,你注意到了吗?如果没有就好好看一下吧。
- 4楼llhhyy19892分钟前
- 嗯哈
- 3楼AGqingshui前天 22:06
- ..........
- 2楼wangqiuyun3天前 08:27
- sql语句拼接是一个最大的错误
- 1楼hejingyuan63天前 08:09
- 学习了