web安全SQL注入中order by后无法参数化

Posted AngieQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web安全SQL注入中order by后无法参数化相关的知识,希望对你有一定的参考价值。

某次被问到:“使用预编译真的绝对安全吗?”
了解到order by和表名、列名等是无法预编译处理的。

  1. 表名、列名无法预编译处理的原因:
    在生成语法树的过程中,预处理器在进一步检查解析后的语法树时,会检查数据表和数据列是否存在,因此数据表和数据列不能被占位符?所替代。但在很多业务场景中,表名需要作为一个变量存在,因此这部分仍需由加号进行SQL语句的拼接,若表名是由外部传入且可控的,仍会造成SQL注入。
  2. ORDER BY后的ASC/DESC也不能被预编译:
    order by,order by后一般是接字段名,而字段名是不能带引号的,比如 order by username;如果带上引号成了order by \'username\',那username就是一个字符串不是字段名了,这就产生了语法错误。一方面预编译又只有自动加引号的setString()方法,没有不加引号的方法;而另一方面order by后接的字段名不能有引号。

更本质的说法是:不只order by,凡是字符串但又不能加引号的位置都不能参数化;包括sql关键字、库名表名字段名函数名等等。

不能参数化的位置,不管怎么拼接,最终都是和使用“+”号拼接字符串的功效一样:拼成了sql语句但没有防sql注入的效果。
但好在的一点是,不管是sql关键字,还是库名表名字段名函数名对于后台开发者来说他的集合都是有限的,更准确点应该说也就那么几个。
这时我们应可以使用白名单的这种针对有限集合最常用的处理办法进行处理,如果传来的参数不在白名单列表中,直接返回错误即可。

以上是关于web安全SQL注入中order by后无法参数化的主要内容,如果未能解决你的问题,请参考以下文章

数据库框架mybatis使用order by 动态参数及#{}和${}的区别

SQL注入 order by后的注入(Less-46)

详解基于MSSQL “order by”语句报错的SQL注入技术

sql注入中order by的作用

java中动态创建的order by子句在Veracode扫描中显示为sql注入问题

一次实战sql注入绕狗