想找SQL注入?遇到这种接口一定要尝试一下!

0x00

SQL注入想必大家都是不陌生的(不了解的可能需要补一补基础了),它的危害自然不必多说,可以说不低于RCE,危害程度已经快拉满了。但是在当前WAF横行,各种开发框架的安全保护下,可以说是十分罕见了(野鸡网站不算)。但是如果你发现某网站允许前端传递自定义字段来对数据进行排序,那也许、可能、有小概率会出现SQL注入点,比如这种请求:

demo.com/order/list?name=xxxx&page=1&size=20&orderBy=createdAt

为什么我会这么说?这里我们就需要先了解一下服务端的处理逻辑,是怎么将一个HTTP请求转换为SQL去执行的。

以下皆以MySQL数据库举例,它也是目前互联网公司使用最多的数据库。

0x01 参数转换

一般情况下,对于查询列表之类的请求,请求参数会包含2个部分,查询条件和分页参数,分别对应上面的key=xxx和page=1&size=20,分别决定我们需要根据什么来过滤数据以及需要返回多少条数据,将它们转换为SQL,可能是下面这样子:

SELECT * FROM t_user WHERE name = 'xxxxx' limit 0, 20

查询名称等于xxxxx的用户,并且返回第0到20条数据。

但是查询条件和分页是前端传过来的,也就是变量,那我们的SQL就也需要根据这两个变量进行动态的变化。以前远古时代,那可能就会直接使用字符串拼接的方式,就像下面这样:

var sql = "SELECT * FROM t_user WHERE name = '" + ${name} + "' limit " + ${(page - 1) * size} + "," + ${size}

这不用多说,全是注入点,比如name参数修改为 ' or 1=1--,那整个SQL就变成了:

SELECT * FROM t_user WHERE name = '' or 1=1 --' limit 0,20

但是这是远古时代的实现方式,这种方式实际上是在代码里面拼接好了SQL,然后再扔给数据库执行,数据库拿到的是一个完整的SQL,直接运行就行了。

现在稍微正规基本上不太可能使用字符串拼接的方式,都是使用SQL预编译。

0x02 SQL预编译

什么是SQL预编译?简单来说,就是我扔给DB的是一个带有占位符的SQL模板,而对应的参数,是分开扔给数据库的。这样数据库在编译SQL的时候,就只按模版编译,在需要执行的时候,才把参数扔进去,这样就没办法通过参数来修改对应的语法树,也就不会有注入了。

想要更详细的了解可以去看一看MySQL的执行流程,预编译最早的目的是为了性能。

比如还是上面的SQL,那使用预编译的方式就变成了这样:

SELECT * FROM t_user WHERE name = ? limit ?, ?

在扔给MySQL执行时,实际上是分别给他传递了预编译SQL,以及对应的参数列表,像这样:

execute(sql, name, page, size);

0x03 order by

那为什么说排序字段会有可能存在注入点呢,比如加上了排序字段,SQL会是下面这样:

SELECT * FROM t_user WHERE name = 'xxxxx' limit 0, 20 order by createdAt

但是MySQL规定,预编译中的参数标记只能用于数据值应出现的地方,而不能用于 SQL 关键字、标识符等。

图片

所以order by后面的表字段是没办法使用的。

那这时候就只能够使用字符串拼接的方式,比如这样:

var sql = "SELECT * FROM t_user WHERE name = ? limit ?, ? order by " + ${orderBy}

不管是什么框架,比如Java系的Mybatis,使用${}代替#{},实质上都是一样的,都是通过字符串拼接代替预编译占位符。

那这时候如果开发不够严谨,直接使用了前端传回来的字符串,那这里就变成了一个SQL注入点了。

如果严谨一点的开发,那在任何没有使用预编译占位符的地方,都会使用白名单的方式进行过滤,仅允许传入白名单内的orderBy属性,那这就没有办法了。

0x04

所以,这就是为什么允许自定义排序的接口上,出现SQL注入点的概率更高了。因为这部分更依赖开发的经验和能力,这就会导致出现漏洞的概率更大了。


欢迎关注我的公众号“混入安全圈的程序猿”,更多原创文章第一时间推送 

  • 25
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值