一.动态拼接sql注入
Select
insert
update
delete
java.sql.Connection
Statement
.execute
.executeQuery
jdbcTemplate
queryForInt
queryForObject
queryForMap
getConnection
PreparedStatement
Statement
execute
jdbcTemplate
queryForInt
queryForObject
queryForMap
executeQuery
getConnection
二.预编译处理不当
setObject()
setInt()
setString()
setSQLXML()
三.框架导致的sql注入
常用关键字
createQuery
session.save
session.update
session.delete
①sql注入基础
public User getUserById(String id) throws SQLException {
Connection connection = JDBCTOOLS.getConnection();
String sql = "select id,username from user where id=" + id;
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
resultSet.next();
int userId = resultSet.getInt(1);
String username = resultSet.getString(2);
User user = new User(userId, username);
return user;
}
②预编译机制
1.预编译常见模式
Hibernate
@Autowired CategoryDAO categoryDAO; //依赖注入
@RequestMapping("/hibernate")
public String hibernate(@RequestParam(name = "id") int id) {
Category category = categoryDAO.getOne(id);
return category.getName();
}
//常用关键字
$
#
Mybatis框架学习
//框架架构理解
(1)加载设置配置:将SQL的配置信息加载成为一个个MappedStatement对象,设置参数映射配置,结果映射配置。
(2) SQL解析:当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,并将最终结果返回。
//模式:预编译模式常用关键字
Mysql:
order by ${id} asc
in (${id})
like '%${id}%'
Oracle:
like '%$id$%'
like '%'||'$id$'||'%'
基于注解的写法
//这里是springboot的写法思路
@Mapper
public interface CategoryMapper {
@Select("select * from category_ where name= '${name}' ")//即select * from name where name=#{name}这种写法就是jdbc的预编译模式写法
public CategoryM getByName(@Param("name") String name);
}
基于xml的写法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.seaii.springboot.mapper.CategoryMapper">
<select id="get" resultType="cn.seaii.springboot.pojo.CategoryM">
select * from category_ where id= ${id}
</select>
</mapper>
2.预编译无法解决产生漏洞的几个点
原因:预编译只能处理查询参数导致的,如
select * from test where name=#{name};
四.特殊规范的sql注入
Spring Data Jpa
https://sec-in.com/article/547
修复方法
采用的模式
①类型转换(一般无数字注入)
#httpServletRequest的getParameter方法获取到的参数的类型都是String
int id = Integer.valueof(req.getParameter("id"));
②预编译
两种思路
①mybatis使用#进行预编译
②参数话固定进行预编译如set(name,"123");采用这种方式进行
③其他三种特殊操控的
④过滤与编码进行修复
一个比较有意思的全局编码替换
keyword.properties的内容如下