MyBatis框架本身具备防SQL注入的能力,但如果开发者使用以下不正确写法,就可能会出现SQL注入漏洞
1、MyBatis
在MyBatis中,${}语法用于直接将变量值插入到SQL语句中,应该使用#{},${_parameter}是直接拼接到SQL中的,没有进行任何过滤或转义
找到应用程序中调用findByUserNameVuln02的地方
构造SQL语句admin' OR '1'='1,成功获取数据
2、MyBatis
在MyBatis中,${}语法用于直接将变量值插入到SQL语句中,应该使用#{},${username}是直接拼接到SQL中的,没有进行任何过滤或转义
找到应用程序中调用findByUserNameVuln01的地方
构造SQL语句admin' OR '1'='1,成功获取数据
3、MyBatis
在MyBatis中,${}语法用于直接将变量值插入到SQL语句中,应该使用#{},${order}是直接拼接到SQL中的,没有进行任何过滤或转义
找到应用程序中调用findByUserNameVuln03的地方
构造SQL语句1 asc--,成功获取数据
JDBC是原生写法,如果开发者使用以下不正确写法,就可能会出现SQL 注入漏洞
1、JDBC
username参数是直接拼接到SQL中的,没有进行任何过滤或转义
构造SQL语句' OR '1'='1,成功获取数据
2、JDBC
这段代码使用了PreparedStatement,PreparedStatement支持参数化查询,可以防止SQL注入攻击,但是由于在创建PreparedStatement对象之前就已经拼接了用户输入,可以看到username参数是直接拼接到SQL语句中的,应该使用参数占位符?而不是直接拼接字符,所以仍然存在SQL注入
构造SQL语句' OR '1'='1,成功获取数据
修复方式
原生JDBC:使用?作为参数占位符,通过正确使用PreparedStatement执行SQL,避免直接拼接用户输入;
MyBatis:使用#{}替换${},#{}底层为预编译,${}为直接拼接,容易导致SQL注入,遇到无法使用预编译的情况,要单独做过滤。