PHP的system()函数本身非漏洞,但不当使用用户可控输入会导致远程命令执行(RCE);须切断“用户输入→system()”通路,严格白名单校验、escapeshellarg()转义,禁用危险函数并采用更安全替代方案。

PHP 的 system() 函数本身不是漏洞,但**不当使用它执行用户可控输入时,会直接导致远程命令执行(RCE)**,这是高危安全风险。关键不在禁用函数,而在切断“用户输入 → system()”这条危险通路。
严格过滤和转义用户输入
如果业务逻辑确实需要调用系统命令(极少见),绝不能把原始 $_GET、$_POST 或文件名等直接拼进 system()。必须做两件事:
- 对输入做白名单校验:例如只允许数字 ID,则用
(int)强转或filter_var($id, FILTER_VALIDATE_INT) - 如需传参给命令,优先改用
escapeshellarg()包裹每个参数,而不是自己拼接字符串 - 避免用
system($cmd . ' ' . $_GET['arg'])这类写法——哪怕加了escapeshellarg(),也建议重构为更安全的替代方案
禁用危险函数(纵深防御)
在 php.ini 中禁用 system、exec、shell_exec、passthru、proc_open 等函数,属于基础加固手段:
- 设置
disable_functions = system,exec,shell_exec,passthru,proc_open,popen,pcntl_exec - 修改后重启 Web 服务(如 Apache 或 PHP-FPM)才能生效
- 注意:该配置对已通过其他方式(如反序列化、扩展漏洞)获得代码执行权限的攻击者无效,仅防初级利用
用更安全的替代方案
绝大多数场景下,system() 都可被更可控的方式替代:
立即学习“PHP免费学习笔记(深入)”;
- 读取文件用
file_get_contents(),而非system('cat file.txt') - 获取目录列表用
scandir()或glob(),而非system('ls -la') - 处理图像/压缩/编码等任务,优先调用 PHP 原生扩展(如 GD、ZipArchive、json_encode)
- 若必须与外部程序交互,考虑使用专用 SDK 或 HTTP API(如调用 FFmpeg 可封装为独立服务并限制访问)
代码审计与最小权限原则
定期检查项目中所有对 system() 及同类函数的调用点:
- 确认是否真有必要;如有,是否完全隔离了用户输入
- 运行 PHP 的 Web 进程(如 www-data)应无权执行敏感操作(如读取 /etc/shadow、写入系统目录)
- 生产环境禁用
display_errors,防止错误信息泄露路径或配置细节



















