https://blog.youkuaiyun.com/weixin_39986856/article/details/83651847
在MyBatis中,“ $ {xxx}”这样格式的参数会直接参与SQL 编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用$ {xxx}“这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。
【结论】在编写MyBatis的映射语句时,尽量采用“ # {xxx}”这样的格式。若不得不使用“ $ {xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。
#{}:相当于JDBC中的PreparedStatement的
$ {}:是输出变量的值
简单说,# {}是经过预编译的,是安全的 ; $ {}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。
如果我们通过语句后用了订单$ {},那么不做任何处理的时候是存在SQL注入危险的。你说怎么防止,那我只能悲惨的告诉你,你得手动处理过滤一下输入的内容。如判断一下输入的参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入侧的参数是否在预期的参数集合中。
2.原理,怎么防止?
发生sql注入的原因是,不安全的参数拼接,编译后,sql执行,如上例子,会出现问题。那怎么防止?
其实在Java JDBC中 我们都知道 有 用 ?占位符去代替参数先进行编译,然后代入参数执行,这样就可以避免注入,why?因为sql注入不安全因素是发生在编译期,用占位符后,就避免了这个问题。
3.mybatis中的防注入?#{} 和${}区别?
其实 #{}正是用了?占位符,而${} (使用场景:order by 这样固定的字段后面,但也要防止安全问题)则是原样代入,mybatis就是用#{}来实现防注入,而底层是用JDBC的PreparedStatement实现的,如上个问题所述。
主要看order by,like,in等可能存在注入点
经典博客:
https://c0d3p1ut0s.github.io/MyBatis%E6%A1%86%E6%9E%B6%E4%B8%AD%E5%B8%B8%E8%A7%81%E7%9A%84SQL%E6%B3%A8%E5%85%A5/
附上java审计资料:
看雪帖子:https://bbs.pediy.com/thread-254317.htm
另外还有上传的资源,其中有mybatis sql。https://download.youkuaiyun.com/download/hujiuding/11826805