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

如何在Nest.js中阻止public目录内的上传文件被执行?

如何阻止public文件夹中用户上传的可执行脚本被执行?

针对你允许用户上传任意类型文件到public目录的场景,要避免恶意脚本执行导致应用崩溃,可以从以下几个方面入手:

1. 禁止服务器解析执行上传的脚本文件

如果你的应用用Node.js(比如Express)提供静态文件服务,默认情况下express.static会根据文件后缀设置Content-Type,比如.js会被设为application/javascript,浏览器会执行它。你可以通过自定义响应头,强制将这类文件标记为纯文本:

app.use('/public', express.static('public', {
  setHeaders: (res, path) => {
    // 匹配常见脚本后缀
    const scriptExtensions = /\.(js|mjs|ts|py|php)$/i;
    if (scriptExtensions.test(path)) {
      res.setHeader('Content-Type', 'text/plain');
    }
  }
}));

这样浏览器拿到脚本文件时会当作纯文本展示,而不会执行。

2. 重命名上传文件,剥离可执行后缀

不要保留用户上传的原始文件名和后缀,改用随机哈希值+非执行后缀命名。比如:

  • 原始文件名:malicious.js
  • 重命名后:a1b2c3d4e5.upload

这样即使文件内容是脚本,因为后缀不属于可执行类型,服务器和浏览器都不会触发执行逻辑。代码示例:

const crypto = require('crypto');

function generateSafeFilename() {
  const hash = crypto.randomBytes(16).toString('hex');
  // 统一用.upload后缀
  return `${hash}.upload`;
}

3. 把上传文件移到非Web可访问目录

不要把用户上传的文件放在public(Web根目录)下,而是新建一个独立的uploads目录(和public同级),然后通过后台接口来提供文件访问。比如在Express中写一个路由:

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

app.get('/uploads/:filename', async (req, res) => {
  const filename = req.params.filename;
  const filePath = path.join(__dirname, 'uploads', filename);
  
  try {
    const content = await fs.readFile(filePath);
    // 根据实际文件类型设置Content-Type,或默认设为text/plain
    res.setHeader('Content-Type', 'text/plain');
    res.send(content);
  } catch (err) {
    res.status(404).send('File not found');
  }
});

这样用户无法直接通过URL访问上传文件,必须通过你的接口,你可以在接口里做更多安全校验。

4. 校验文件真实类型(不要只看后缀)

用户可能会把脚本文件改成.jpg后缀绕过检查,所以要基于文件内容判断真实类型。可以用file-type库:

const { fileTypeFromFile } = require('file-type');

async function checkFileType(filePath) {
  const fileType = await fileTypeFromFile(filePath);
  if (!fileType) {
    // 无法识别的类型,直接拒绝或标记为危险
    return false;
  }
  // 允许的类型白名单,比如只允许图片、文档等
  const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf', 'text/plain'];
  return allowedTypes.includes(fileType.mime);
}

如果检测到是脚本类型的文件,可以直接拒绝上传,或者转义内容后再存储。

5. 设置文件系统权限

在服务器上,给上传的文件设置严格的权限,禁止执行权限:

  • Linux/macOS:执行chmod 644 /path/to/public/uploads/*,只保留读写权限,去掉执行权限
  • Windows:右键文件→属性→安全→设置所有用户的执行权限为拒绝

这样即使有人尝试在服务器端执行文件,也会因为权限不足失败。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:17:47