持久层Mybatis中对于SQL注入的问题,聊聊你的想法?

354 阅读2分钟

这是我参与8月更文挑战的第14天,活动详情查看:8月更文挑战

SQL注入:

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息

在mybatis 中最常见的注入风险是书写的时候使用${}

image.png

   上述图片表述的JDBC的利用两种预编译事时的方式;

  • 第一种

preparedStatement可以直接写sql语句,然后是executeUpdate;

 防止sql注入

  • 第二种是:Statement,不能直接写,executeUpdate表示直接执行的sql语句,

是直接的字符串拼接

image.png

mybatis获取参数值的两种方式:

1. #{}--->preparedStatement表示通配符下的预编译语句,会将#{}转换成???


SQL语句一般是

  insert  into payment (serial) values(#{serial});
  
  --不用去管单引号的问题,因为在String赋值的时候,他会自动的添加, 比如‘男’
  

2.${}-->利用的是Statement的对象使用字符串拼接的方式来操作SQL

 


SQL语句一般是

  insert  into  serial values('${serial}');
  '${serial}'
  
  --必须要管单引号的问题,他不会自动的添加,可能导致出错误;

mybatis #{}和${}的区别是什么

本质:#{}是预编译处理,$}是字符串替换。

(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

(2)mybatis在处理${}时,就是把${}替换成变量的值。

(3) 使用#{子可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。

(4)预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因 为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入

总结

对于 预编译之后的SQL,可以直接将SQL注入的条件排除,做到非侵入性;