urldecode()解码引发注入其实也没那么可怕

简介: urldecode()解码引发注入其实也没那么可怕

引子

事情是这样的,这次小马写了一个关于判断前端传参是否有汉字并对汉字进行校验的功能,代码如下:

image.png

有听到很多同学说,要特别注意urldecode的二次解码注入问题。于是搜索了相关资料,大部分说的关于这个urldecode二次解码引发注入的问题是这样的:

因为对于编码的字符串 ,PHP本身在处理提交的数据之前会进行一次urldecode解码(大豆存在于PHP5.3以上),然后一般后端接收到参数,自然而然会再进行一次urldecode函数解码,因为和urlencode()成双成对的嘛。这原本看起来也没什么问题,因为两次urldecode并不会影响结果值。比如urldecode('你好'),得到的还是‘你好’,自然问题不在于这里。

urldecode二次解码有注入风险

问题在于:如果我们构造字符串/getUser.php?id=%2527520%2527,提交后PHP自行解码,%25解码成了%,得到url是/getUser.php?id=%27520%27;注意了,这个时候,我们的urldecode()函数登场了,正儿八经地进行了一次解码,将%27解码成了’,于是最终得到的url是 /test.php?id='520'。原理就是: echo urldecode(urldecode('%2527520%2527')); 得到 '520'。

在后端得到这个url是非常敏感的,因为这很容易让人想到单引号SQL注入。PHP中常用的过滤函数如addslashes()、mysql_real_escape_string()、mysql_escape_string()或者使用魔术引号GPC开关来防止注入,原理都是给单引号(’)、双引号(”)、反斜杠(\)和NULL等特殊字符前面加上反斜杠来进行转义。而这些都容易被urlencode后的字符串绕过。如%2527520%2527很容易被校验和过滤函数直接通过,但其实解码后是含有特殊字符的,这样就容易有SQL注入风险,只要构造playload让id二次解码后等于 '520' or 1=1 就可以注入了。让URL解码后得到?id='520' or 1=1将得到如下语句,获取得到所有用户数据:

select * form user where id='520' or 1=1;

image.png

其实没那么可怕

不要慌,其实没那么可怕。这个只是在于参数校验失守,底层DAO又没在最终入库的时候转义特殊字符才有可能发生的。但是这两道防线目前基本很少被攻破,因为主流的框架大多数接收处理后,在入库之前都会进行参数校验和过滤,一般都封装了底层的DAO,在入库之前还有最后一层mysql_real_escape_string()转义特殊字符,如果不去修改底层,一般问题不大。除非自己写的架子,多注意一下就好了。

总结

如何避免这个问题的总结:

从前端接收完提交参数,urldecode完尽量先做参数处理,在参数进入逻辑之前最后进行参数校验和过滤,如开头的代码图,再次校验参数中含有的字符是否符合规范;

前面不管如何处理,如何转码,入库之前一定要做最后的转义(转义在最后,不要先转义再urldecode再入库,这样就很危险了)。

顺带一提:rawurldecode()也会产生同样的问题,因此在使用这两个函数都需要多注意一下就可以了。

相关文章
|
10月前
|
SQL 安全 PHP
|
5月前
|
SQL 安全 测试技术
Burpsuite Decoder解码功能实战
Burpsuite Decoder解码功能实战
|
9月前
揉碎HTTP编码过程,从此不乱码
揉碎HTTP编码过程,从此不乱码
|
9月前
|
存储 IDE Unix
C primer plus 学习笔记 第8章 字符输入/输出 和输入验证
C primer plus 学习笔记 第8章 字符输入/输出 和输入验证
类似%-30的字串解码办法
类似%-30的字串解码办法
79 0
|
Web App开发 Java
Javaweb 响应字节流输出中文乱码问题
Javaweb 响应字节流输出中文乱码问题
394 0
Javaweb 响应字节流输出中文乱码问题
|
存储 缓存 安全
诡异的字符串问题。。。
说问题前,我先跟各位读者聊一下字符串这个话题,谈起字符串也就离不开数据结构
164 0
诡异的字符串问题。。。
CoreGraphic 框架解析
CoreGraphic框架解析(一)—— 基本概览CoreGraphic框架解析(二)—— 基本使用CoreGraphic框架解析(三)—— 类波浪线的实现CoreGraphic框架解析(四)—— 基本架构补充
1003 0
|
JSON 前端开发 JavaScript
说说JSON和JSONP,也许你会豁然开朗
JSON(JavaScript Object Notation) 和 JSONP(JSON with Padding) 虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。
1306 0
|
JavaScript 前端开发
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等