最危险的路径遍历漏洞是直接拼接用户输入与基础目录:如os.path.join(base_dir, request.args.get("file")),未规范化、未白名单校验,且存在“先拼接后校验”逻辑错误。

检查文件路径拼接是否直接使用用户输入
这是最常见也最危险的模式:后端拿到 file 参数后,不做任何清洗,直接和基础目录拼接。比如 os.path.join(BASE_DIR, request.args.get("file")) 或 path.Join("static/", fileName)。一旦用户传入 ../../../etc/passwd,拼接结果就脱离了预期范围。
排查时重点看三类代码位置:
- 所有调用
send_file、http.ServeFile、open()、fread()等读取文件的入口函数 - 参数来源是否来自 URL query、POST body、Header(如
X-File-Path)或 cookie - 是否有“先拼接、再校验”的逻辑——这种顺序错误会让校验形同虚设
验证是否做过路径规范化与白名单校验
很多开发者以为做了“过滤 ../”就安全了,但绕过手法极多:.//、%2e%2e%2f、....//、..\(Windows)、甚至 URL 编码嵌套(%252e%252e%252f)。真正有效的防御是做完解码后再做路径规范化,然后比对是否仍在授权目录内。
检查代码中是否执行了以下任一操作:
- 调用
os.path.realpath()或filepath.EvalSymlinks()获取真实路径 - 用
strings.HasPrefix(realPath, allowedBase)(Go)或realpath.startswith(allowed_base)(Python)做前缀判断 - 拒绝任何
realPath不以预设安全目录开头的情况(注意:不能只检查原始字符串)
测试时别只盯着 ../../../etc/passwd
浏览器会自动解析并“优化” URL 中的 ../ 段,导致你手动在地址栏输 /dashboard/../etc/passwd 实际发出去的是 /etc/passwd——这反而可能绕过某些粗粒度过滤。真正的穿越行为必须靠工具发包验证。
实操建议:
- 用
curl -v "https://target/download?file=..%2f..%2f..%2fetc%2fpasswd"(URL 编码的../) - 用 Burp Suite 重放请求,关闭 “URL decode” 选项,确保原始 payload 被完整发送
- 优先尝试
/proc/self/cmdline(Linux)或C:\windows\win.ini(Windows),比/etc/passwd更少被 WAF 拦截
留意静态资源服务中间件的隐式风险
像 Express 的 express.static()、FastAPI 的 StaticFiles、或 Gin 的 StaticFS,默认不拦截带 ../ 的路径段——只要路由匹配成功,就会交给底层文件系统处理。而很多框架的兜底路由(如 NoRoute)又会 fallback 到静态服务,这就给了攻击者钻空子的机会。
典型高危组合:
- 路由规则为
/public/*,但没限制*的内容 -
fallbackToFrontend类函数中,用strings.TrimPrefix()处理路径后直接path.Join() - 前端构建产物目录(如
admin-dist/)被硬编码为根路径,却未做路径合法性检查
这类问题往往不在业务代码里,而在框架配置或中间件逻辑中,容易被忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











