目录遍历漏洞怎么修复
目录遍历漏洞怎么修复?目录别急着加过滤器,先看看你的遍历业务逻辑
上个月某客户被扫出个高危漏洞,攻击者把请求里的漏洞`../../etc/passwd`拼进去,服务器真就把文件吐出来了。修复开发急得满头汗,目录第一反应是遍历“加个关键词黑名单”。我直接拦住了——那玩意儿治标不治本,漏洞绕过方式多到你怀疑人生。修复
目录遍历的目录本质,是遍历**用户输入被当成了文件路径的一部分**。修复的漏洞核心就一句话:**别信输入,别拼路径**。修复但具体怎么做,目录得看你的遍历代码长啥样。
最彻底的漏洞办法:别用用户输入拼路径
如果你在写新代码,直接放弃“根据文件名读取文件”这种模式。改成**用ID或索引关联文件**。比如用户要下载报告,传参是`report_id=42`,后端维护一张映射表,42对应服务器上某个固定文件。用户永远碰不到真正的路径字符串。
这招最狠,但老项目改起来伤筋动骨。那就退一步,用**规范化+前缀校验**:
base_dir = "/var/www/files/" user_path = request.get("path") full_path = os.path.normpath(os.path.join(base_dir, user_path)) if not full_path.startswith(base_dir): return "非法请求" 注意`normpath`会处理掉`..`和多余的斜杠,拼完再检查结果是否还在允许的目录内。这里有个坑——`startswith`要用`os.path.commonpath`比较,否则`/var/www/files_evil`这种目录也能蒙混过关。
别忽略编码和系统差异
你以为过滤了`../`就完事了?攻击者可以URL编码成`%2e%2e%2f`,或者用16进制编码、Unicode编码绕过去。更阴的是Windows系统反斜杠`\`、正斜杠`/`都认,Linux只认`/`。你过滤了正斜杠,人家换个反斜杠在Windows服务器上照样穿。
所以**别做黑名单**,做白名单。明确允许哪些字符——只允许字母、数字、下划线、点号,其他全拒。文件名里真要有点号,那就格外小心,`.php`、`.ini`这种后缀得单独拦。
文件系统层面也得上锁
代码写对了还不够。假设你的web服务用`www-data`用户跑的,那这个用户对文件系统的权限就得收着点。只给它读指定目录的权限,别让它能碰`/etc`、`/home`。用`chroot`或者容器隔离更好,就算代码有漏洞,文件系统也看不全。
我见过一个案例,代码写得没问题,但服务器上有个符号链接指向了根目录,照样被绕过去。所以**定期检查目录里有没有奇怪的软链接**,也是运维的基本功。
最后说个反直觉的事
有些框架自带防护,比如Java的`Path.normalize()`、Python的`pathlib`,但别迷信。框架帮你挡了一部分,业务代码里一个`new File(request.getParameter("file"))`就把防护全绕了。我见过最离谱的修复方式——把`..`替换成空字符串,结果人家传`.../...//`,过滤完还剩`../`,照样穿。**修复漏洞前,先写个能复现漏洞的测试用例**,修完跑一遍,再想想还有没有别的编码方式能绕过。
目录遍历不是高科技漏洞,但你轻视它,它就能让你一夜回到解放前。现在去翻翻你代码里所有处理文件的地方,看看有没有直接拼路径的——有的话,今天该加班了。









