php慎用urldecode函数

By | 2013/01/07

在php中urldecode和urlencode是一对双胞胎,如果在url中包含了中文,urlencode函数属于必用的。为什么呢?

因为中文有很多编码,简体主要有gb2312和utf-8这两种,其中主流的浏览器都默认是utf-8编码的。所以在url包含了汉字时,浏览器会把汉字作为utf-8编码发送(部分浏览器为解决字符集问题会做urlencode功能相同的编码),而大部分的php服务端也都采用utf-8,这样就不会出现乱码问题。

可像ie6这样的老家伙,总是喜欢使用gb2312进行传送,这样到了服务器端接收就成了乱码。为了保证我们程序的可靠性,对url中的中文部分进行urlencode是一直良好的习惯! 可能使用urlencode习惯了,在接收参数的时候我们也习惯用urldecode进行解码,因为他们本来就是一对嘛……岂不知这样就带来了一个安全隐患。经过查询php手册得知,对于编码后的字符串发送到服务器端,php总是会自动进行解码,而我们再使用urldecode函数就是进行了二次解码,虽然这个没问题,但是带来了安全隐患。 比如编码后的字符串%2527提交到后台,php首先进行一次自动解码,%25编码后是%,因此我们收到的字符串是%27,而如果这时我们调用了urldecode的话,会再次进行解码,%27变为’,这样就成功了躲过了我们过滤系统,而这样的注入目前还没有几个程序的脚本可以检测到。 所以说,我们多次一举还带来了安全隐患,当你看到这个文章的时候,urldecode是废弃的时候了!

注:发现了点意外,有的服务器并不对urlencode后的编码自动解码,而文中提到“对于编码后的字符串发送到服务器端,php总是会自动进行解码”,猜测至少是5.3以上版本才会这样。但这不影响urldecode是一个“危险”的函数,目前发现多例因此函数而出错的sql注入绕过。

ps:一个好的实践是,对接收的数据做多次urldecode转码,确保没有编码的数据后再进入注入检测脚本。

6 thoughts on “php慎用urldecode函数

  1. 曾先生

    我这边就遇到了,获取参数被自动urldecode,“+”号变成了空格,但是实际我获取的字符串里面是含有“+”号的,自动转换是出错的,请问我该如何解决这个问题,不让PHP获取参数的时候,自动urldecode呢?麻烦了,请你将解决方法发到我的邮箱,谢谢!

    Reply
    1. admin Post author

      您应该考虑对输入内容进行编码而不是继续使用+号,然后从服务器端提供支持。因为加号在html里面,等同于空格,这就像&在url是用来间隔键值对一样。举个例子,你现在是遇到了加号问题,如果某一天内容总突然有了“&”符号,怎么处理?所以最好的实践是对内容进行编码。

      Reply
  2. 匿名

    “经过查询php手册得知,对于编码后的字符串发送到服务器端,php总是会自动进行解码”
    能否直接在PHP.ini里关闭,这个自动urldecode呢?我这边就遇到这种麻烦了

    Reply
  3. 匿名

    经过查询php手册得知,对于编码后的字符串发送到服务器端,php总是会自动进行解码

    Reply
  4. 陈军

    其实我只是在看关于urlencode相关函数的。我看你这个所谓的安全问题只能说明你对编解码以后的内容没有进行二次转义处理导致的问题。我不管怎么样,即使是session的信息,我也不信任。

    Reply
    1. admin Post author

      很高兴可以探讨这个话题,提出这个问题只是因为容易被忽略。因为大部分程序的安全依赖一次性的检测,一般会有函数在代码执行伊始进行一次检测,而urldecode之类就提供了躲过去的可能。内容的转义一般也之后进行一次转义,很少进行两边。

      Reply

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据