判断上传文件是否为php脚本需分层验证:先检查内容中合法php开始标记并跳过注释与字符串,再用token_get_all解析语法结构,最后结合服务器配置确认是否可执行,并排除图片马、phar伪装等混淆手法。

判断上传文件是否为 PHP 脚本,不能只看后缀名或 MIME 类型,因为这两者都极易被伪造。真正可靠的方式是结合内容检测、语法解析与执行环境特征,分层验证。
检查文件内容是否含 PHP 标签
PHP 脚本最基础的特征是包含可执行的 PHP 开始标记,如 <?php 、、(JSP 风格但某些配置下也会被解析)、<code><script language="php"> 等。需注意:</script>
- 用
file_get_contents()读取文件前几 KB(避免大文件内存压力),再用preg_match()检查是否存在合法 PHP 开始标记; - 跳过注释块(
/* */、//、#)和字符串字面量内的伪标记(如"<?php "),否则易误报; - Windows 下需处理换行符差异(
\r\n),Linux/macOS 下为\n,建议统一用str_replace(["\r\n", "\r"], "\n", $content)规范化。
尝试解析 PHP 语法结构
利用 PHP 自身的词法分析能力,比正则更严谨:
- 调用
token_get_all(file_get_contents($tmp_file)),若返回非空且首个有效 token 是T_OPEN_TAG(如<?php),说明具备基本 PHP 结构; - 若解析过程中抛出警告(如因编码问题或不完整标签),可用
@抑制并视为非 PHP; - 注意:该方法不执行代码,仅做词法扫描,安全可控。
验证是否能被当前环境解析执行
即使内容含 PHP 标签,也不代表服务器会执行它——最终取决于 Web 服务器配置:
- 检查目标路径是否在 Apache 的
AddType application/x-httpd-php .xxx或 Nginx 的fastcgi_split_path_info规则覆盖范围内; - 对上传目录,确认无
php_flag engine off或<files> Require all denied</files>类限制; - 若已知服务器存在
.htaccess解析漏洞,还需检查上传文件是否可能被配套的.htaccess文件“激活”为 PHP。
排除常见混淆与伪装手法
攻击者常将 PHP 代码隐藏在看似安全的载体中:
- 图片马:用十六进制编辑器在 JPG 文件末尾追加
<?php phpinfo(); ?>,需读取文件尾部 1–2 KB 检查; - PHAR 文件:含恶意反序列化 payload,扩展名可能是
.jpg,但文件头为504841522E3130("PHAR.10" 十六进制); - Base64/gzinflate 混淆:搜索
eval\(gzinflate\(base64_decode\(|@assert\(base64_decode\(等典型模式; - 空字节/特殊后缀:如
shell.php%00.jpg、shell.pHp、shell.php.,需在服务端规范文件名后再判断原始内容。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











