PHP中一个馒头引发的血案

PHP中一个馒头引发的血案

既然是血案,那就先说说这个血案吧。

我使用Yii框架(PHP的一套开源框架)开发一套系统,其中有个功能是校验码,就是Yii的captcha,一开始工作的好好的,captcha可以显示出来,后来系统又做了一些改动,结果captcha显示不出来了。

然后查captcha的使用方法是不是什么地方有错,网上差了大量的资料,查来查去,没发现是用法错误啊。在查看httpd的错误log,还有Yii框架自身的错误log,也没有发现什么可疑之处,后来查资料知道Yii的captcha内部是使用GD库或者Imagick来生成二维码的,于是还把gd库给升级版本,结果问题依旧。

二维码其实一张png图片,这个可以通过看生成的网页的HTML内容就可以看到

<img src="/controller/view?v=xxxxx"></img>

然后使用curl命令

$ curl -v http://www.youdomainname.com/controller/view?v=xxxx

。。。。

< HTTP/1.1 200 OK
< Date: Wed, 20 Jan 2016 07:07:14 GMT
< Server: Apache/2.2.15 (CentOS)
< X-Powered-By: PHP/5.3.3
< Set-Cookie: PHPSESSID=7rot42vkbl0eq8u1tllrf9m7i7; path=/
< Expires: 0
< Cache-Control: must-revalidate, post-check=0, pre-check=0, public
< Content-Transfer-Encoding: binary
< Vary: Accept-Encoding
< Content-Length: 3773
< Connection: close
< Content-Type: image/png

。。。。

这个命令是输出请求这个url的时候的输入和输出的详细信息,包括http的header部分,header会告诉你,内容是什么,这里显示 image/png,也就是说是png图片,接下来保存它

$ curl http://www.youdomainname.com/controller/view?v=xxxx -o my.png

然后使用imagick的display来显示它,当然你也可以用其他的工具来显示它,

结果提示说这个png图片的头部不对。然后我们用二进制的查看器查看,linux下面可以用hexedit这个工具查看,结果显示第一个字节是0A,这个是 \n的16进制表示,而png的标准的头格式的第一个字节应该是 89, 接下来是 50 4E 47,也就是说我们多输出了一个换行符。不信的话,可以hexedit或者其他的二进制文件编辑器去掉这个0A,看看这个图片能不能正常显示。我真的试了,果然是这样。

接下来就调查为什么会多输出一个换行符号呢?

默认所有的controller都是继承自CController.php,而我让所有的controller继承自一个自定义的controller,这个controller中包含了另外一个文件,这个文件中做了一些检测搜索引擎的爬虫的事情。如果我在自定义的controller中去掉include这个文件,则二维码可以正常工作了,也就是说问题处在这个文件上,那么接下来怎么办?我们再次使用curl来直接访问这个文件

$ curl -v http://www.youdomainname.com/myquestion.php

结果发现就是输出一个字符,这个字符刚好就是我们前面的看到的那个多出来的字符 0A,然后一行行的去掉里面的代码,结果全部去到玩,只剩下<?php ?>,结果还是有个这个字符输出,后来仔细一看在 ?>后面跟着一个空行,原来这就是我们要找的那个馒头。哎呀,当初手真是欠啊,你说为什么要多按一下那个回车啊。

好了解释一下为什么这个馒头会引发这个血案,原因大部分人都知道,<?php  ?>之外的东西,都会被原样输出。而生成captcha的代码就是把controller执行一遍再加上通过gd库生成的图片的内容发送给客户端。

这个问题搞了我半天的时间,我去!

 

好累。。。。

版权所有,禁止转载. 如需转载,请先征得博主的同意,并且表明文章转载自:IT夜班车,否则按侵权处理.

    分享到:

留言

你的邮箱是保密的 必填的信息用*表示