MyBatis如何防止SQL注入

SQL注入起因

SQL注入是一种常见的攻击方式,攻击者或者误操作者通过表单信息或者URL输入一些异常的参数,传入服务端进行SQL处理,可能会出现这样的情况delete from app_poi where poi_id = (输入参数):

输入参数:10 or 1 = 1

SQL拼接:delete from app_poi where poi_id = (10 or 1 = 1)

执行结果:app_poi中的所有数据都会被delete

这种问题出现的原因可能是攻击者故意为之,也可能是误操作,那么服务端该如何处理,避免这样的问题出现呢?

MyBatis

MyBatis是一种半自动化持久化框架,所有SQL操作都需要我们通过配置文件或者注解的方式手动编辑,它提供了一种类函数的功能,用户提供输入,MyBatis根据输入类型和输入参数进行验证,如果参数没有问题,那么MyBatis就针对合法的输入提供输出,即

用户输入参数+用户输入类型 ---> MyBatis检测 ---> 返回输出

接下来通过配置文件和注解两种方式来进行说明

  • 配置文件:
<delete id= "deletePoiById"  parameterType= "java.lang.Integer" >
     DELETE
     FROM app_poi
     where poi_id = #{poiId}
</delete>
  • 基于注解
@delete ( "delete from app_poi where poi_id = #{poiId}" )
public  void  deletePoiById( @Param ( "poiId" ) Integer poiId);

MyBatis对用户输入的数据会检测其类型是否和parameterType标识的类型一致,如果一致,则进行后续拼接处理,否则抛出异常,SQL就不会执行

对于10 or 1 = 1这种输入,和java.lang.Integer类型不同,就会abort并抛出异常

原理

MyBatis使用#{}防止SQL注入,其实使用的是PreparedStatement,PreparedStatement会对执行SQL进行预编译,这个过程是发生在数据库服务端,也就是说,对于PreparedStatement的SQL需要两次网络请求,首次是获取PreparedStatement,第二次才是发起SQL执行;

PreparedStatement会对SQL中输入的参数进行检测,并在SQL都是用问号来设置占位符,即只允许传入一个参数,像(10 or 1 = 1)这种明显不会被占位符所接受

String类型SQL注入

对于数字类型参数#{}可以很好的解决SQL注入,其原因不难理解,那么对于string类型的呢?Mybatis只是使用了一个占位符并不能解决该问题

<delete id= "deletePoiById"  parameterType= "java.lang.String" >
     DELETE
     FROM app_poi
     where content = #{content}
</delete>

如果content的内容是“美食 or 1 = 1”,那么数据将会被全部清除

解决该问题,还是结合传统方式,使用正则表达式匹配,总结常见的需要摒弃的string,替换为空即可,例如string包含

and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|; |or|-|+|,等

转载于:https://www.cnblogs.com/he-px/p/7592028.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值