CVE-2012-1823是PHP-CGI在CGI模式下将HTTP查询字符串误解析为命令行参数导致的远程代码执行漏洞,影响PHP < 5.3.12版本;攻击者可通过-d、-s等参数触发源码泄露或执行任意PHP代码。

php-cgi 在 5.3.11 及更早版本中存在一个**可被远程利用的参数解析绕过漏洞(CVE-2012-1823)**,本质是 CGI 模式下对请求参数的错误处理导致任意代码执行。
这个漏洞不是 PHP 解释器本身的内存或逻辑缺陷,而是 php-cgi 二进制在作为独立 CGI 程序运行时,把 HTTP 请求中的查询字符串(query string)误当成命令行参数来解析,从而触发了 PHP 的 `-d`、`-s`、`-c` 等危险开关。
为什么 CGI 模式会出这个问题?
Apache 或 Nginx 配置不当,将所有.php 请求直接转发给 php-cgi 二进制(而非通过 mod_php 或 php-fpm),且未限制其接收外部参数。此时,攻击者构造形如 /index.php?-d+allow_url_include%3don+-d+auto_prepend_file%3dphp://input 的 URL,php-cgi 就会把 -d 当作运行时配置指令执行,开启 allow_url_include 并强制在每个脚本前加载 php://input —— 这意味着后续 POST 的任意 PHP 代码都会被执行。
常见错误现象
- 访问
/index.php?-s直接返回源码(PHP 语法高亮输出) - 访问
/index.php?-d+auto_prepend_file%3d/etc/passwd返回系统密码文件内容 - 配合
php://input+ POST 数据,直接 getshell
关键参数与影响范围
-
-s:触发语法高亮,暴露源码(低危但常用于探测) -
-d allow_url_include=on:开启远程文件包含,是 RCE 链的关键一环 -
-d auto_prepend_file=php://input:让服务端读取并执行你 POST 的全部内容 - 影响版本:PHP 5.3.12 之前所有 CGI 模式部署的版本,包括 5.2.x、5.3.0–5.3.11
防御实操建议
立即学习“PHP免费学习笔记(深入)”;
- 禁用 CGI 模式:改用
php-fpm或mod_php,它们不接受 URL 参数作为命令行开关 - Web 服务器层拦截:Nginx 中加
location ~ \.php(.*)$ { if ($query_string ~ "^(.*?)(\?|&)(?:\-d|\-s|\-c|\-a|\-p|\-t|\-u|\-v|\-z).*$") { return 404; } };Apache 可用RewriteCond %{QUERY_STRING} ^.*(\-d|\-s|\-c|\-a|\-p|\-t|\-u|\-v|\-z).*$ - 确认
phpinfo()页面里Server API显示为CGI/FastCGI就要立刻检查 —— 这是风险信号 - 即使升级到新版 PHP,若仍用
php-cgi直接暴露在 Web 前端,漏洞逻辑依然成立
php-cgi 的调用方式本身就是一个独立攻击面。只要 CGI 接口还开着,且没做参数过滤,哪怕 PHP 是 8.2,只要它被当命令行程序跑,就可能重演类似问题。



















