怎么在 Apache 中阻止上传脚本被直接解析执行

作者:袖梨 2026-07-14
核心是切断上传目录中脚本文件与PHP处理器的关联,应优先用SetHandler None清除绑定,其次考虑php_flag engine off(仅模块模式),并配合FilesMatch正则覆盖多后缀绕过,如(?i:php|php3|phtml|phar|php[3-8]|phps),确保在Directory块或.htaccess中精准生效。

核心是切断上传目录中脚本文件与 PHP 处理器的关联,不是靠删后缀或改权限——Apache 仍可能按多后缀规则误解析。关键在配置层级和指令选型:优先用 SetHandler None 清除绑定,其次考虑 php_flag engine off(仅限模块模式),.htaccess 方案需权限支持。

按目录精准禁用解析(推荐)

/var/www/html/uploads 这类纯文件存放目录,直接在虚拟主机或主配置中加 <Directory> 块:

  • 方式一(兼容性强,推荐):
    <Directory "/var/www/html/uploads"><br>  <FilesMatch ".(?i:php|php3|php4|php5|phtml|phar)$"><br>    SetHandler None<br>  </FilesMatch><br></Directory>

    它让 Apache 忽略所有匹配后缀的处理器绑定,哪怕文件叫 shell.php.jpg 也不会触发 PHP 解析。
  • 方式二(仅模块模式可用):
    <Directory "/var/www/html/data"><br>  php_flag engine off<br></Directory>

    注意:PHP-FPM 模式下该指令无效,会报错;且不能写在 .htaccess 中,除非主配置允许 AllowOverride Options=All

堵住多后缀绕过漏洞

Apache 默认从右往左识别后缀,a.php.jpg 可能被当作 PHP 执行(若 .jpg 未注册 MIME 类型)。必须配合 FilesMatch 覆盖所有常见组合:

  • 正则要覆盖大小写:".(?i:php|phtml|phar|php[3-8]|phps)$"
  • 避免只禁 .php —— 攻击者常用 .php3.phtml 或双后缀如 .php.jpg
  • 若用 Require all denied,它只是拒绝访问,不阻止解析;真正防执行必须用 SetHandler Noneengine off

共享主机场景下的 .htaccess 方案

无主配置权限时,在上传目录放 .htaccess

  • 确保主配置已设 AllowOverride All 或至少 AllowOverride Options=All
  • 内容示例:
    <FilesMatch ".(?i:php|php3|php4|php5|phtml)$"><br>  Require all denied<br></FilesMatch>

    这能阻止访问,但不如 SetHandler None 彻底(因不涉及处理器层面);适合 Apache 2.4+ 环境。
  • 旧版 Apache(2.2)用 Order Deny,Allow + Deny from all,但已不推荐

验证是否真正生效

配置后必须实测,避免被更高优先级配置覆盖:

  • 上传测试文件 test.php,内容为 <?php echo 'executed'; ?>
  • curl -I http://yoursite.com/uploads/test.php 查看响应头:
    成功应返回 Content-Type: text/plain403 Forbidden,而非 200 OK 且含 PHP 输出
  • 检查 Apache 错误日志:tail -f /var/log/httpd/error_log,确认无 Invalid command 'php_flag' 等报错

相关文章

精彩推荐