文件上传表单必须使用每次请求动态生成并绑定 session 的 csrf token,后端需严格校验,否则易遭伪造上传;flask 中应启用 csrfprotect 并配合 filefield 和 validate_on_submit(),token 必须置于 form data 同级,禁放 url 或 header;csrf 防御仅阻提交者,不防恶意内容,须叠加 mime 校验、扩展名白名单、路径隔离与执行权限禁用。

文件上传表单必须带 CSRF token,否则等同于裸奔
没有 csrf_token 的文件上传表单,攻击者能用任意页面构造 <form method="POST" action="/upload"></form> 并自动提交,只要用户登录态还在,后端就会照单接收——哪怕你用了 accept=".pdf,.docx" 或前端 JS 校验,这些全可绕过。
常见错误包括:token 硬编码在 HTML 模板里、从 localStorage 读取、用时间戳或递增 ID 生成。这些都让 token 可预测,失去防伪造意义。
- 后端每次渲染上传页面时,必须调用安全随机函数(如 Node.js 的
crypto.randomBytes(32)、Python 的secrets.token_urlsafe(32))生成新 token - 该 token 必须绑定当前 session,存入服务端 session 存储(如 Redis 或数据库),不能只存在客户端
- 前端只负责把
<input type="hidden" name="csrf_token" value="...">嵌入表单,禁止用 JS 读取、赋值、缓存或重发
Flask 中用 CSRFProtect + FileField 是最简可靠组合
Flask 默认不带 CSRF 防护,需显式启用 CSRFProtect 扩展,并配合 FileField 使用。它会自动为每个表单注入隐藏字段,并在校验阶段比对 session 中的 token 值。
关键点不是“有没有 token”,而是“token 是否随每次请求刷新”和“是否校验失败即拒收”。很多项目只加了 @csrf.exempt 或漏写 validate_on_submit(),等于形同虚设。
- 初始化时启用:
csrf = CSRFProtect(app),并确保SECRET_KEY已设置且足够强 - 表单类中必须继承
FlaskForm,且字段含FileField时,仍需显式调用form.validate_on_submit()—— 它内部会触发 CSRF 校验 - 不要手动删掉
form.hidden_tag(),它会输出csrf_token字段;若自定义渲染,务必保留<input name="csrf_token" ...>
enctype="multipart/form-data" 不影响 CSRF 校验逻辑
文件上传必须设 enctype="multipart/form-data",但这只是告诉浏览器如何编码二进制数据,对 CSRF token 的传输和校验无任何干扰。token 仍是普通表单字段,随 multipart body 一起发送,后端解析时先提取字段再比对。
容易踩的坑是:误以为 multipart 会“冲掉” token,于是额外用 AJAX 分两步传(先传 token 再传文件),反而破坏原子性,增加竞态风险。或者把 token 放在 URL 参数里,暴露在日志和代理中。
- token 始终走 form data,和文件字段同级,都在同一个
multipart/form-data请求体中 - 后端框架(如 Flask、Django、Express + csrf)均支持在 multipart 解析阶段提取并校验 token,无需手动干预
- 避免将 token 放在 query string 或 request header 中,防止被缓存、记录或跨域泄露
文件上传 CSRF 的隐蔽性远超普通表单
普通 CSRF 攻击常表现为“点一下就改密码”,而文件上传 CSRF 更难察觉:攻击者可诱导用户上传一个看似无害的图片,实则在服务器上写入 WebShell(如 PHP 文件),后续通过直接访问触发执行。尤其当后端未重验 MIME 类型、未过滤文件名、未限制执行权限时,危害指数级放大。
所以 CSRF 防护只是第一道门,必须叠加文件头校验、扩展名白名单、保存路径隔离、执行权限禁用等措施。单独靠 token,防不住已上传的恶意文件被执行。
- CSRF token 防的是“谁提交”,不防“提交了什么”——后者靠服务端文件校验
- 上传后若提供直接访问链接(如
/uploads/shell.php),且服务器允许执行 PHP,则 token 再严也没用 - 真正安全的上传路径应是不可执行目录(如
/var/www/static/uploads/),且 Web Server 配置禁止该路径下脚本执行
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











