PHP 5.3.4起修复00截断漏洞,改用带长度标记的Zend字符串结构,关键函数显式使用Z_STRLEN()获取真实长度,不再依赖\0终止符,并在文件包含前校验路径是否含\0,从内核层杜绝截断。

PHP 5.3.4 版本起,官方修复了因 NULL 字符(即 ASCII 0x00,URL 编码为 %00)导致的字符串截断行为,因此 00 截断上传漏洞不再存在。根本原因在于底层字符串处理逻辑的变更,而非简单地“过滤掉 %00”。
具体来说:
在 PHP realpath()、
fopen()、include、文件保存路径拼接等)在处理 C 风格字符串时,会将遇到的第一个0x00视为字符串终止符(C string null terminator),直接截断后续内容。
例如:传入文件名"shell.php%00.jpg",经 URL 解码后变成"shell.php\0.jpg",系统在解析路径时只取"shell.php",.jpg被丢弃,最终保存为可执行的shell.php。PHP 5.3.4 的修复方式是:统一改用带长度标记的 Zend 字符串结构(
zval中的string类型)替代纯 C 字符串操作。所有关键路径处理函数(如php_strip_url_password()、expand_filepath()、php_open_temporary_file()等)都显式检查并使用Z_STRLEN()获取真实长度,不再依赖\0结束判断。-
同时,
;若存在,则直接报错或拒绝加载,不再静默截断。include/require等文件包含函数在解析文件路径前,会先验证路径中是否含<p>同时,<code>include/require等文件包含函数在解析文件路径前,会先验证路径中是否含\0;若存在,则直接报错或拒绝加载,不再静默截断。立即学习“PHP免费学习笔记(深入)”;
此外,
magic_quotes_gpc虽在 5.4.0 中被彻底移除,但它在低版本中对%00的转义(变为\0)只是缓解手段,并非根本修复——而 5.3.4 的更新是从内核层杜绝了该类截断逻辑。
所以,不是“高版本更严格过滤”,而是 PHP 放弃了以 \0 为字符串边界的旧范式,转向安全、明确的长度控制机制。这也解释了为何即使关闭所有过滤、构造完美 payload,在 5.3.4+ 环境中也无法触发 00 截断。



















