2012年5月3日
某些基于 CGI 的设置(Apache+mod_php 和 nginx+php-fpm 不受影响)中存在一个漏洞,至少 8 年来一直未被发现。 CGI 规范的第 7 节 指出
某些系统支持一种向 CGI 脚本提供字符串数组的方法。这仅在“索引”查询的情况下使用。这由带有 URL 搜索字符串(不包含任何未编码的“=”字符)的“GET”或“HEAD”HTTP 请求识别。
因此,在某些 CGI 实现中,不包含“=”的查询字符串的请求与包含“=”的请求的处理方式不同。对于 PHP 来说,这意味着包含 ?-s 的请求可能会转储页面的 PHP 源代码,但包含 ?-s&=1 的请求则没问题。
大量站点将 PHP 作为 Apache 模块(通过 mod_php)或使用 nginx 下的 php-fpm 运行。这些设置都不容易受到此漏洞的影响。直接使用 Shebang 样式的 CGI 似乎也不容易受到此漏洞的影响。
如果您使用 Apache mod_cgi 运行 PHP,则可能容易受到攻击。要查看您是否容易受到攻击,只需在任何 URL 的末尾添加 ?-s。如果您看到源代码,则表示您容易受到攻击。如果您的站点正常呈现,则表示您没有受到攻击。
要解决此问题,请更新到 PHP 5.3.12 或 PHP 5.4.2。
我们认识到,由于 CGI 是一种相当过时的运行 PHP 的方式,因此将这些站点升级到 PHP 的现代版本可能不可行。另一种方法是配置您的 Web 服务器,不允许这些类型以 "-" 开头且不包含 "=" 的查询字符串的请求通过。添加这样的规则不应该破坏任何站点。对于使用 mod_rewrite 的 Apache,它看起来像这样
RewriteCond %{QUERY_STRING} ^(%2d|-)[^=]+$ [NC]
RewriteRule ^(.*) $1? [L]
如果您正在编写自己的规则,请务必考虑 urlencoded ?%2ds 版本。
雪上加霜的是,我们的 bug 系统中存在一个 bug,它会在对 bug 报告的评论中将 bug 报告的私有标志切换为公开,导致此问题在我们有时间对解决方案进行充分测试之前就公开了。请通过 bugs.php.net 报告任何问题。
如需下载 PHP 5.3.12 和 PHP 5.4.2 的源代码,请访问我们的 下载页面,Windows 版本的二进制文件可在 windows.php.net/download/ 找到。 ChangeLog 已经存在。