验证preparedStatement防止SQL注入

mysql> select * from t_u
    -> ;
+----+----------+------+------+
| id | username | pwd  | age  |
+----+----------+------+------+
|  1 | zs       | test |   22 |
+----+----------+------+------+
1 row in set (0.14 sec)

mysql> update t_u set pwd = 'ddd\' or \'1\'=\'1' where id =1;
Query OK, 1 row affected (0.39 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from t_u;
+----+----------+----------------+------+
| id | username | pwd            | age  |
+----+----------+----------------+------+
|  1 | zs       | ddd' or '1'='1 |   22 |
+----+----------+----------------+------+
1 row in set (0.06 sec)
java:
package web;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; 

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 

import util.DBUtil;

public class LoginServletSafe extends HttpServlet{ 
		public void service(HttpServletRequest req,
				 				HttpServletResponse res)
				throws ServletException,IOException{ 
			System.out.println("========================");
			Connection conn =null; 	
			try{
				conn = DBUtil.getConnection(); 
			String username = req.getParameter("username");
			String pwd =req.getParameter("pwd"); 
			String sql="select * from t_u where username = ? and pwd = ?";
			System.out.println(sql); 
			PreparedStatement prep= conn.prepareStatement(sql); 
			prep.setString(1, username);
			prep.setString(2, pwd); 
			//System.out.println("pwd的值:"+pwd);
			//若将pwd的值定义为:ddd' or '1'='1 
			//通过preparedStatement预编译后,执行的SQL语句将是:
			//select * from t_u where name = 'zs' 
			// and pwd ='ddd\' or \'1\'=\'1'
			
			 /**实现机制不同,注入只对sql语句的准备(编译?)过程有破坏作用
				而ps已经准备好了,执行阶段只是把输入串作为数据处理,不再
				需要对sql语句进行解析,准备,因此也就避免了sql注入问题.
				
				*PreparedStatement可以在传入sql后,执行语句前,给参数赋值,
				*避免了因普通的拼接sql字符串语句所带来的安全问题,而且准备sql
				*和执行sql是在两个语句里面完成的,也提高了语句执行的效率
				*/
			ResultSet rst= prep.executeQuery();
			
			System.out.println("rst: "+rst);
			//System.out.println("rst: "+rst.getStatement());
			//判断结果集rs是否有记录,并且将指针后移一位
			//因为前面的select语句是限定的条件,只有满足了条件才能有记录产生
			if(rst.next()){   
				System.out.println("success");
			}else{
				System.out.println("fail");
			}
			
			}catch(Exception e){
				e.printStackTrace();
				throw new ServletException(e);
			}
			
			
		}


}

然后在JSP页面中,name的取值为zs,pwd的取值为:ddd' or '1'='1 

提交后,控制台打印出:success,就表示,pwd的值是当成参数值来传递了,相当于执行了以下的SQL语句。


mysql> select * from t_u where username='zs' and pwd = 'ddd\' or \'1\'=\'1';
+----+----------+----------------+------+
| id | username | pwd            | age  |
+----+----------+----------------+------+
|  1 | zs       | ddd' or '1'='1 |   22 |
+----+----------+----------------+------+
1 row in set (0.00 sec)

验证完毕,一直纠结网络上也没有这么的详细的解释,自己弄明白后,豁然开朗。^_^

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值