NestJS路径遍历漏洞下为何无法下载.env文件?
NestJS路径遍历漏洞中无法下载.env文件的疑问
我在NestJS应用中发现了路径遍历漏洞,相关下载中间件代码如下:
async use(req: Request, res: Response) { const baseUrl = req.baseUrl; const params = req.params.param; const folderName = params[0]; const fileName = params[1]; const path = `${folderName}/${fileName}`; const filePath = getFilePath(path); const authorized = await this.accessService.verifyCallerCanDownload(req, filePath); return res.download(filePath); }
攻击者无法通过/api/download/../../main.js直接访问文件,因为应用会把..和..分别解析为folderName和fileName。但可以通过URL编码绕过:比如/api/download/%2e%2e%2f../main.js(%2e%2e%2f对应../),此时应用会将../../识别为folderName,main.js为fileName,从而下载服务器源码。
同一目录下存在.env等敏感文件,我能下载其他敏感文件,但请求/api/download/%2e%2e%2f../.env时,服务器抛出NotFoundError: Not Found,但该文件实际存在。
我的疑问:NestJS是否有内置保护机制阻止.env文件被访问?为什么能下载其他文件却无法获取.env?
核心结论
NestJS本身没有内置阻止.env文件下载的专属机制,无法访问.env的原因大概率来自以下几个方面:
- 静态服务默认配置影响:如果你的应用同时使用了Express的静态文件服务(NestJS默认基于Express),
express.static的默认配置中dotfiles参数值为'ignore',会自动忽略以.开头的文件。若getFilePath函数或accessService复用了这类过滤逻辑,可能会排除.env这类隐藏文件。 - 文件系统权限限制:服务器上的
.env文件可能设置了更严格的权限(比如仅允许拥有者读取),而Node.js进程的运行用户没有读取该文件的权限,导致res.download无法找到文件。 - 自定义逻辑过滤:
getFilePath函数或accessService.verifyCallerCanDownload方法中,可能存在对文件名的过滤规则,比如直接排除以.开头的文件,导致.env被拦截。 - 反向代理或Web服务器限制:如果应用前端部署了Nginx、Apache等反向代理服务器,这些服务可能配置了阻止访问.env文件的规则(比如通过location匹配或rewrite规则),导致请求在到达NestJS之前就被拦截。
额外建议:修复路径遍历漏洞
当前中间件的路径解析逻辑存在严重风险,建议通过以下方式加固:
- 定义一个安全的根目录,所有下载请求必须限制在该目录内
- 使用
path.resolve或path.join结合根目录来生成绝对路径,避免路径遍历 - 验证生成的文件路径是否在安全根目录范围内
示例代码:
const safeRoot = path.resolve('./authorized-downloads'); // 替换为你的安全目录 const resolvedPath = path.resolve(safeRoot, folderName, fileName); // 检查路径是否在安全根目录内,防止遍历 if (!resolvedPath.startsWith(safeRoot)) { return res.status(403).send('非法请求'); } const authorized = await this.accessService.verifyCallerCanDownload(req, resolvedPath); return res.download(resolvedPath);
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

