使用preparedStatement来解决sql注入漏洞

使用Statement来执行sql语句,如果语句中连接的有变量,那么可以对变量进行一些修改使绕过sql语句的判断条件。比如:

public static boolean login(String username,String password) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		boolean flag = false;
		try {
			conn = DriverManager.getConnection();
			stmt = conn.createStatement();
			String sql = "select * from user where username ='"+username+"' and password ='"+password+"' ";
			rs = stmt.executeQuery(sql);
			if(rs.next()) {
				flag = true;
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//释放资源
		}
		return flag;
	}

代码中,传入username 和password来进行用户验证。如果传入的username为:"aaa' or ' 1=1"或者"aaa' --",其中aaa为存在的用户名。那么即使密码输入错误,也会通过验证。原因是,sql语句变为了:select * from user where username ='aaa' or 1=1 and password = 'xxxxx'或者是:select * from user where username ='aaa' -- password = 'xxxxx'        那么,密码验证就不起作用了。

使用PreparedStatement避免此问题。

public static boolean login2(String username,String password) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		boolean flag = false;
		try {
			conn = JDBCUtils.getConnection();
			String sql = "select * from user where username=? and password=?";
			//预处理Sql
			pstmt = conn.prepareStatement(sql);
			//设置具体参数
			pstmt.setString(1, username);
			pstmt.setString(2, password);
			
			rs = pstmt.executeQuery();
			if(rs.next()) {
				flag = true;
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.release(rs, pstmt, conn);
		}
		return flag;
	}

这里,sql语句使用了占位符?(大概其他符号也可以)。这就意味着,sql语句中不会出现其他关键字,如'--','#','or'等等。出现了也会做出相应的处理予以忽略。再使用PreparedStatement的setString(第n个占位符 , 字符串)来进行设置。

猜你喜欢

转载自blog.csdn.net/wargon/article/details/81087678
今日推荐