You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何防止恶意利用RewriteRule访问/home/以外的目录?

路径遍历漏洞的防范方案

我们的网站通过mod_rewrite的RewriteRule规则,将形如example.org/home/products/widgets/的目录请求转换为example.org/home/index.php?path=/products/widgets/的请求,当前使用的规则如下:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^(.+)/$ ./index.php?path=$1 [NC,QSD,NS]
</IfModule>

index.php会列出对应真实目录下的文件详情,但存在安全隐患:攻击者可以构造example.org/home/index.php?path=/products/../../secretstuff这类请求,绕过限制访问/home/以外的目录。

下面是可靠的检测和防范方案,两种方式可以结合使用:


一、用mod_rewrite做前置拦截

可以在现有规则里增加过滤条件,直接拦截包含../的恶意请求,同时限制请求路径的范围:

修改后的规则示例:

<IfModule mod_rewrite.c>
  RewriteEngine On
  # 拦截包含../的请求,直接返回403禁止访问
  RewriteCond %{QUERY_STRING} (\.\./)+ [NC]
  RewriteRule ^ - [R=403,L]

  # 保留原有的目录转index.php规则
  RewriteCond %{REQUEST_FILENAME} -d
  RewriteRule ^(.+)/$ ./index.php?path=$1 [NC,QSD,NS]
</IfModule>

这种方式能在请求到达PHP代码前就拦下大部分简单攻击,但要注意攻击者可能用URL编码(比如%2e%2e%2f)绕过,所以这只能作为第一道防线,不能完全依赖。


二、PHP代码用realpath()做核心验证(最可靠)

仅靠mod_rewrite不够彻底,必须在PHP代码层做严格验证,这是解决问题的关键:

  1. 先确定允许访问的根目录(比如/home/的绝对路径)
  2. 把用户传入的path参数和允许目录拼接,用realpath()解析成真实的绝对路径
  3. 检查解析后的路径是否完全在允许目录范围内

示例代码:

<?php
// 定义允许访问的根目录,换成你实际的绝对路径
$allowedRoot = realpath($_SERVER['DOCUMENT_ROOT'] . '/home/');
$requestPath = $_GET['path'] ?? '';

// 拼接并解析真实路径
$targetPath = realpath($allowedRoot . '/' . $requestPath);

// 验证路径是否合法:必须存在且在允许的根目录内
if (!$targetPath || strpos($targetPath, $allowedRoot) !== 0) {
    http_response_code(403);
    exit('非法访问');
}

// 后续逻辑:列出$targetPath下的文件详情
?>

realpath()会自动处理所有相对路径(比如../、.),转换成真实的绝对路径,不管攻击者用什么方式构造路径,都能准确判断是否越权,这是最可靠的防护手段。


总的来说,建议同时使用两种方式:mod_rewrite拦截大部分恶意请求,减轻后端压力;PHP代码层的验证作为核心,彻底杜绝路径遍历风险。

内容的提问来源于stack exchange,提问作者GrahamS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:17:34