PreparedStatement是如何防止SQL注入的?

PreparedStatement是如何防止SQL注入的?

 

1 什么是SQL注入?

Statement statement = connection.createStatement();
String user = "1' OR ";
String password = "='1' OR '1' = '1";
//使用Statement,SQL语句使用字符串拼接
String sql = "SELECT user,password FROM user_table WHERE USER = '" + userName + "' AND PASSWORD = '" + password+ "'";
statement.execute(sql);

在MySQL的日志文件中

#条件出现  '1'='1'  恒成立,出现bug
SELECT USER,PASSWORD FROM user_table WHERE USER = '1' OR ' AND PASSWORD = '='1' OR '1' = '1';

以上出现的情况被认为是SQL注入

 


 

2 PreparedStatement可以解决SQL注入问题

 

2.1 PreparedStatement的使用

  • 举例如下:
// '?'为通配符,需要填充
String sql = "SELECT user,password FROM user_table WHERE USER = ? AND PASSWORD = ?"
PreparedStatement ps = connection.prepareStatement(sql);
//填充占位符,其中args为占位符('?')的填充内容,填充从1开始
for(int i = 0;i < args.length;i++){
	ps.setObject(i + 1, args[i]);
}
ps.excute();

 

2.2 PreparedStatement是如何解决SQL注入问题的?

  • 我们在使用Connection获取PreparedStatement对象时,会把SQL语句作为参数传入,此时,SQL语句会在PreparedStatement对象初始化的时候进行一次预编译。在内存中执行如下:

com.mysql.jdbc.JDBC42PreparedStatement@b1a58a3: SELECT user,password FROM user_table WHERE USER = ** AND PASSWORD = **

 

  • 当我们对占位符进行填充的时候就是替换上面的’**’,而当出现字符时系统会在内存中自动进行转译,结果如下:

com.mysql.jdbc.JDBC42PreparedStatement@b1a58a3: SELECT USER,PASSWORD FROM user_table WHERE USER = ‘1\’ OR ’ AND PASSWORD = '=\‘1\’ OR \‘1\’ = \‘1’;

 
实际在MySQL中执行的是

SELECT USER,PASSWORD FROM user_table WHERE USER = "1' OR " AND PASSWORD = "='1' OR '1' = '1";

不会对SQL语句修改。

 


3 总结

PreparedStatement能够防止SQL注入的主要原因是能够实现预编译,在对占位符进行填充的时候会对符号进行转译处理。所以,平常我们最好是别使用Statement,使用PreparedStatement进行替换。

 
 

参考:栖息之鹰-PreparedStatement是如何防止SQL注入的?

以上内容纯手打,码字不易,如需转载请声明出处,谢谢!
作者:LouisHaoL

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值