SQL攻击与PreparedStatement

1.什么是SQL攻击。

    在需要用户输入的地方,用户输入的是SQL语句的片段,最终用户输入的SQL片段与我们DAO中写的SQL语句合成一个完整的SQL语句!例如用户在输入用户名以及登陆密码都是SQL语句时,我们的程序就会将其嵌入到我们的SQL语句中,最终可能出现数据库的错误。

2.PreparedStatement

1)它是Statement接口的子接口;

2)强大之处

    2.1)防SQL攻击。

    2.2)提高代码的可读性。

    2.3) 提高效率


实例:

public boolean login(String username,String password) throws Exception{
		ResultSet re = null;
		Connection con = null;
		Statement stmt = null;
		String sql = "select * from users where Id = '"
					+username+"' and Password = '"+password+"'";
		boolean result = false;
		try{
			//设置四大参数
			String driverClassName = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://localhost:3306/timebookstore";
			String sqlUserName = "***";
			String sqlPassword = "123456";
			//加载类
			Class.forName(driverClassName);
			//连接数据库获取Connection对象
			con = DriverManager
					.getConnection(url,sqlUserName,sqlPassword);
			//获取Statement,用于向数据库发送SQL语句
			stmt = con.createStatement();
			//发送查询语句
			re=stmt.executeQuery(sql);
			result = re.next();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(re != null)re.close();
			if(stmt != null)stmt.close();
			if(con != null)con.close();
		}
		return result;
	}
	
	@Test
	public void fun2() throws Exception{
		String username = "abc";
		String password = "123";
		System.out.println(login(username,password));
	}

控制台输出的结果是false,表示验证不成功。但是如果用户名和密码改为如下:

@Test
	public void fun2() throws Exception{
		String username = "abc' or 'a' = 'a";
		String password = "123' or 'a' = 'a";
		System.out.println(login(username,password));
	}

也即完整的sql语句为:

select * from users where Id = 'abc' or 'a' = 'a' and Password = '123' or 'a' = 'a'

很明显这一句查询语句返回表中的所有内容,所以结果是true。这就是sql攻击.


下面的例子使用PreparedStatement防止sql攻击。

public boolean login(String username,String password) throws Exception{
		ResultSet re = null;
		Connection con = null;
		PreparedStatement pstmt = null;
		String sql = "select * from users where Id = ? and password = ?";
		boolean result = false;
		try{
			//设置四大参数
			String driverClassName = "com.mysql.jdbc.Driver";
			String url = "jdbc:mysql://localhost:3306/timebookstore";
			String sqlUserName = "***";
			String sqlPassword = "123456";
			//加载类
			Class.forName(driverClassName);
			//连接数据库获取Connection对象
			con = DriverManager
					.getConnection(url,sqlUserName,sqlPassword);
			//获取PreparedStatement,用于向数据库发送SQL语句
			pstmt = con.prepareStatement(sql);
			//设置sql的参数
			pstmt.setString(1, username);
			pstmt.setString(2,password);
			//执行sql语句
			re=pstmt.executeQuery();
			result = re.next();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(re != null)re.close();
			if(pstmt != null)pstmt.close();
			if(con != null)con.close();
		}
		return result;
	}
	
	@Test
	public void fun2() throws Exception{
		String username = "abc' or 'a' = 'a";
		String password = "123' or 'a' = 'a";
		System.out.println(login(username,password));
	}

使用PreparedStatement的结果是false,与我们预期的一样了。

由上面的例子可以看出使用PreparedStatement,编写的sql语句更加直观,还可以防sql攻击。

String sql = "select * from users where Id = '"+username+"' and password = '"+password+"'";//Statement
String sql = "select * from users where Id = ? and password = ?";//PreparedStatement

?号表示参数,下面有设置该参数的代码。

pstmt = con.prepareStatement(sql);
			//设置sql的参数
			pstmt.setString(1, username);
			pstmt.setString(2,password);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值