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

Node.js:通过Express参数获取文件是否安全?需防注入吗?

你的这段Node.js路由代码存在严重安全风险,必须修复!

嘿,这段代码绝对不安全,而且存在典型的路径遍历漏洞——攻击者完全可以轻松访问到/content/includes目录以外的文件,必须立刻添加防护措施!

为什么会有风险?

直接将用户可控的req.params.slug拼接到文件路径里,是路径遍历攻击的典型场景。举个例子:如果攻击者请求/api/includes/../secret,拼接后的路径会变成__dirname/content/includes/../secret.html,这相当于直接跳到上级目录读取secret.html文件。要是攻击者用多组../,甚至能遍历到系统级敏感文件(比如Linux下的/etc/passwd、Windows下的系统配置文件)。

必须做路径遍历防护!

当然需要,而且是优先级极高的修复。这里的“注入防护”具体指路径遍历攻击的防护,核心目标是确保最终生成的文件路径始终严格限制在你预期的/content/includes目录范围内。

实用修复方案(组合使用效果最佳)

  • 限制输入字符:用正则表达式约束slug只能包含合法文件名字符(比如字母、数字、下划线、短横线),直接过滤掉../、\这类危险字符。
  • 使用安全的路径拼接方法:借助Node.js的path模块(path.join或path.resolve)拼接路径,它会自动处理简单的路径遍历序列,但这还不够,必须配合路径校验。
  • 强制校验路径范围:先把目标目录转为绝对路径,再检查最终生成的文件路径是否以这个绝对路径开头,确保不会跳出预期目录。

修复后的示例代码

const path = require('path');
const fs = require('fs');

// 定义允许访问的目录绝对路径,避免相对路径歧义
const allowedDir = path.resolve(__dirname, 'content/includes');

app.get('/api/includes/:slug', (req, res) => {
  const slug = req.params.slug;
  
  // 第一步:校验输入格式,拒绝非法字符
  if (!/^[a-z0-9_-]+$/i.test(slug)) {
    return res.sendStatus(400); // 返回非法请求状态码
  }

  // 第二步:用path.join安全拼接路径
  const filePath = path.join(allowedDir, `${slug}.html`);

  // 第三步:双重校验,确保路径未跳出允许范围
  if (!filePath.startsWith(allowedDir)) {
    return res.sendStatus(403); // 返回禁止访问状态码
  }

  // 最后检查文件是否存在并返回
  if (fs.existsSync(filePath)) {
    res.sendFile(filePath);
  } else {
    res.sendStatus(404);
  }
});

这样处理后,就能有效阻断路径遍历攻击,确保用户只能访问/content/includes目录下的合法.html文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:12:38