Java预编译一些场景下的局限.md

0x00 Mybatis框架

#$的区别

  • #号会点语句进行预编译
  • ${ } 只是进行string 替换,动态解析SQL的时候会进行变量替换

0x01 预编译一些场景下的局限

  • 表名作为变量时,需使用拼接
select * from `user`   
select * from 'user' #报错,表名不能使用单引号
  • order by后需要使用拼接
select * from user order by name
select * from user order by 'name' # 语义发生改变,没有排序的效果了 

0x02 之前有听人说order by后面的语句是不会参与预编译?

这句话是错误的。Order
by也是会参与预编译的。从我们上面的jdbc的setString算法可以看到,是因为setString会在参数的前后加上’’,变成字符串。导致order
by失去了原本的意义。只能说是预编译方式的order by不适用而已。所以对于这种order
by的防御的话建议是直接写死在代码里面。对于order by方式的注入我们可以通过返回数据的顺序的不同来获取数据。

0x03 为什么预编译能让传入的数据只能是数据,它的底层原理是怎样的?

通常来说,一条SQL语句从传入到运行经历了生成语法树、执行计划优化、执行这几个阶段。在预编译过程中,数据库首先接收到带有预编译占位符?的SQL语句,解析生成语法树(Lex),并缓存在cache中,然后接收对应的参数信息,从cache中取出语法树设置参数,然后再进行优化和执行。由于参数信息传入前语法树就已生成,执行的语法结构也就无法因参数而改变,自然也就杜绝了SQL注入的出现。这样一个深刻而简单的原因,相信已经解答了我们最开始的疑问。

猜你喜欢

转载自blog.csdn.net/god_zzZ/article/details/123449134
今日推荐