← 返回题目列表

文件上传场景前端需要注意哪些安全问题?

中等 第 21 / 26 题 更新于 2026/07/29
前端安全文件上传校验用户输入

简化版

文件上传是高风险入口。前端可以做文件类型、大小、数量、扩展名、预览和交互限制,但不能作为安全边界,因为攻击者可以绕过页面直接请求接口。真正安全必须由服务端校验 MIME、文件头、大小、病毒扫描、存储隔离、访问权限和文件名处理。前端重点是减少误传、避免预览 XSS、不要信任文件名和客户端 MIME。

详细版

前端上传校验提升体验,服务端校验保证安全。

风险前端措施服务端必须做
超大文件限制 size限制请求体和存储
伪造类型accept + MIME 提示检查文件头
恶意 SVG/HTML安全预览转存、净化或禁止
文件名注入展示转义重命名和路径隔离
<input type="file" accept="image/png,image/jpeg" />

文件上传要记住:前端校验是用户体验,服务端校验才是安全边界。

完整版教学

一、为什么上传危险

文件上传让用户把任意内容交给系统。攻击者可能上传脚本、超大文件、伪造图片、压缩炸弹、带宏文档、恶意 SVG 或构造特殊文件名。

如果系统把上传文件当静态资源直接执行或预览,风险会放大。

二、前端能做什么

前端适合做体验型拦截:

  • 限制文件大小。
  • 限制文件数量。
  • 提示允许类型。
  • 上传前预览。
  • 进度和取消。
  • 分片上传和失败重试。
function validate(file: File) {
  if (file.size > 5 * 1024 * 1024) throw new Error('文件过大')
  if (!['image/png', 'image/jpeg'].includes(file.type)) throw new Error('类型不支持')
}

三、为什么前端校验不可信

攻击者可以绕过浏览器页面,用 curl、脚本或改包直接请求上传接口。accept 只是文件选择器提示,不是强制安全策略。

file.type 也来自浏览器识别和客户端信息,不能作为唯一依据。

四、服务端必须做什么

服务端要重新校验:

校验项说明
大小限制防磁盘和带宽打爆
文件头判断真实类型
文件名重命名,避免路径穿越
存储域和主站隔离
扫描病毒、恶意内容
权限下载访问鉴权

上传目录不要允许执行脚本。

五、预览也有安全问题

前端预览图片时常用 Object URL:

const url = URL.createObjectURL(file)
img.src = url

用完要 URL.revokeObjectURL(url)。对于 SVG、HTML、PDF 等可执行或复杂格式,预览要非常谨慎,避免脚本执行或插件漏洞。

六、文件名展示要转义

文件名来自用户输入,展示时不能直接插入 HTML。

nameEl.textContent = file.name

不要用 innerHTML = file.name,否则特殊文件名可能造成 DOM 注入。

七、常见误区与追问

  • 误区:input accept 能防止上传非法文件。 accept 只是选择器提示,接口必须服务端校验。
  • 误区:file.type 一定可信。 MIME 可能为空或被伪造,服务端要看文件头和内容。
  • 误区:图片上传就没有 XSS。 SVG、文件名、预览容器和解析器都可能带来风险。
  • 追问:为什么上传文件最好独立域名存储? 降低和主站 Cookie、脚本执行上下文耦合的风险。
  • 追问:前端如何防超大文件? 读取 file.size 做体验拦截,但服务端仍要限制请求体。
  • 追问:文件名如何处理? 前端展示转义,服务端重命名并禁止路径穿越。

八、加强记忆

上传安全记成“两层”:前端拦体验,后端保安全。类型、大小、文件名、预览、存储域和权限都要管,尤其别信客户端给你的任何文件信息。