PreparedStatement是如何防止SQL注入的?

 为什么在Java中PreparedStatement能够有效防止SQL注入?这可能是每个Java程序员思考过的问题。

 

首先我们来看下直观的现象(注:需要提前打开

String param = "'test' or 1=1"; String sql = "select file from file where name = " + param; // 拼接SQL参数 PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet resultSet = preparedStatement.executeQuery(); System.out.println(resultSet.next());
复制代码

输出结果为true,DB中执行的SQL为

复制代码
-- 永真条件1=1成为了查询条件的一部分,可以返回所有数据,造成了SQL注入问题
select
file from file where name = 'test' or 1=1
复制代码

 

2. 使用PreparedStatement的set方法设置参数

复制代码
String param = "'test' or 1=1"; String sql = "select file from file where name = ?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, param); ResultSet resultSet = preparedStatement.executeQuery(); System.out.println(resultSet.next());
复制代码

输出结果为false,DB中执行的SQL为

select file from file where name = '\'test\' or 1=1'

我们可以看到输出的SQL文是把整个参数用引号包起来,并把参数中的引号作为转义字符,从而避免了参数也作为条件的一部分

 


 

接下来我们分析下源码(以mysql驱动实现为例)

打开java.sql.PreparedStatement通用接口,看到如下注释,了解到PreparedStatement就是为了提高statement(包括SQL,存储过程等)执行的效率。

复制代码
An object that represents a precompiled SQL statement.
A SQL statement is precompiled and stored in a PreparedStatement object.
This object can then be used to efficiently execute this statement multiple times.
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信