目录遍历漏洞修复
作者:时尚 来源:娱乐 浏览: 【大 中 小】 发布时间:2026-10-17 06:06:44 评论数:
目录遍历漏洞,目录说白了就是遍历攻击者通过构造特殊的路径请求,绕过访问控制,漏洞直接读取服务器上本不该他看的修复文件。我见过最典型的目录案例,某政府网站的遍历管理员后台,仅靠一个../就被人翻出了/etc/passwd,漏洞甚至数据库连接配置文件直接暴露在web根目录下。修复这漏洞不稀奇,目录但修起来,遍历很多人修得稀里糊涂。漏洞
修复的修复第一原则,不是目录过滤,而是遍历“不做拼接”。很多开发者的漏洞习惯是,用户传一个文件名,代码里就拼一个file_get_contents('/var/www/files/' . $_GET['file'])。这思路本身就危险,再怎么过滤,总有漏网之鱼。比如编码绕过——%2e%2e%2f,或者双写....//,再或者利用Windows下的..\。你堵一个,他换一个,永远在打地鼠。
正确做法是,把用户输入当作一个“标识符”,而不是“路径”。比如,文件ID用数字,然后服务端维护一张映射表,ID对应真实文件路径。用户传file=3,你查表,返回第3个文件。传file=../../etc/passwd?对不起,查表查不到,直接拒绝。这法子不酷,但绝对有效。我一个朋友的项目组当年用这招,之后三年没再被目录遍历骚扰过。
如果业务场景确实需要传文件名,那就必须做“规范化校验”。用realpath()函数把用户输入的路径解析成绝对路径,然后检查这个绝对路径是否在你允许的目录前缀之下。注意,这里有个坑——realpath()对不存在的文件会返回false,所以你得先检查文件是否存在,或者用dirname()逐级验证。另外,别迷信basename(),它只能去掉路径中的目录部分,但如果文件名本身包含..,它可不管。
还有个细节容易被忽略:URL解码的顺序。服务器一般会先URL解码再交给应用,但有些中间件会解码两次。你要是只过滤一次,攻击者把%252e%252e%252f传进来,第一次解码变成%2e%2e%2f,你的过滤规则看的是原始输入,没拦住,等二次解码后就成了../。这种双重编码绕过,我亲眼见过一个安全团队排查了一整天才找到原因。
再补一刀——不要只盯web层。如果服务器上跑着Nginx,你还要确认alias配置有没有问题。Nginx的alias指令有个经典坑:location /files/ { alias /var/www/; },请求/files../secret.txt时,某些版本会解析成/var/www/../secret.txt。这种配置层面的漏洞,代码写得再安全也白搭。
最后说个很多人不知道的检查方法。你修完之后,别只测../,用Burp拦个包,把路径改成/..;/试试——分号在Tomcat里会被当成分隔符,有些解析器会因此跳过路由检查。还有,试试超长路径,比如几千个../叠加,有些老版本IIS会崩溃,崩溃后反而暴露物理路径。修漏洞不是改一行代码就完事,你得把服务器、中间件、应用三层都过一遍。
说白了,目录遍历的根子在于“信任了不该信任的输入”。你把它当数据,它就安全;你把它当路径,它就迟早出问题。这道理简单,但真到写代码的时候,很多人脑子里只有“跑通功能”,没有“提防输入”。修完这次,不妨给团队立个规矩:所有涉及文件操作的接口,一律走ID映射,不接受任何形式的路径参数。省心,也省命。
