CSRF攻击如何影响文件上传 如何添加token防护

来源:开发教程作者:小诸葛头衔:草根站长
导读:本期聚焦于小伙伴创作的《CSRF攻击如何影响文件上传 如何添加token防护》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《CSRF攻击如何影响文件上传 如何添加token防护》有用,将其分享出去将是对创作者最好的鼓励。

CSRF(跨站请求伪造)攻击的核心逻辑是攻击者诱导已登录目标网站的用户,在用户的浏览器中发起一个指向目标网站的伪造请求,这个请求会自动携带用户的登录凭证(比如Cookie),让服务器误以为是用户主动发起的合法操作。文件上传功能如果没有对应的防护机制,就很容易被CSRF攻击利用。

CSRF攻击如何影响文件上传 如何添加token防护

CSRF攻击对文件上传的影响

当网站的文件上传接口没有做CSRF防护时,攻击者可以构造一个恶意页面,页面中包含自动提交的文件上传表单。只要用户访问这个恶意页面,并且此时用户刚好登录了目标网站,浏览器就会自动携带用户的Cookie向目标网站的文件上传接口发送请求,上传攻击者指定的文件。

这种攻击可能带来的危害包括:

  • 上传恶意脚本文件,比如PHP、JSP木马,获取服务器控制权
  • 上传违规内容,导致网站被封禁
  • 上传大体积文件,消耗服务器存储和带宽资源
  • 上传伪装成正常文件的恶意程序,诱导其他用户下载

CSRF Token防护原理

CSRF Token的防护逻辑是服务器为每个用户会话生成一个随机、不可预测的字符串(即Token),并将这个Token嵌入到前端的表单或者请求头中。当用户提交文件上传请求时,需要携带这个Token,服务器收到请求后会验证Token的合法性:如果Token不存在或者不匹配,就拒绝请求,从而识别并拦截CSRF伪造的请求。

前后端添加Token防护的实现步骤

1. 后端生成并返回Token

首先后端需要在用户登录或者访问文件上传页面时,生成一个CSRF Token,保存到用户的会话中,同时返回给前端。以下是Java Spring Boot的实现示例:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.UUID;

public class CsrfTokenUtil {
    // 生成Token并存入session
    public static String generateToken(HttpServletRequest request) {
        String token = UUID.randomUUID().toString().replace("-", "");
        HttpSession session = request.getSession();
        session.setAttribute("csrf_token", token);
        return token;
    }

    // 验证Token
    public static boolean verifyToken(HttpServletRequest request, String clientToken) {
        HttpSession session = request.getSession();
        String serverToken = (String) session.getAttribute("csrf_token");
        if (serverToken == null || clientToken == null) {
            return false;
        }
        return serverToken.equals(clientToken);
    }
}

2. 前端表单嵌入Token

前端在文件上传表单中,需要添加一个隐藏的输入框,用来存放后端返回的CSRF Token。以下是HTML表单的示例:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>文件上传</title>
</head>
<body>
    <form action="/upload" method="post" enctype="multipart/form-data" id="uploadForm">
        <!-- 隐藏的CSRF Token输入框 -->
        <input type="hidden" name="csrf_token" value="${csrfToken}">
        <input type="file" name="file">
        <button type="submit">上传文件</button>
    </form>
</body>
</html>

如果是前后端分离的项目,前端可以通过接口获取Token,然后添加到请求头中,以下是JavaScript的示例:

// 获取CSRF Token
fetch('/getCsrfToken')
    .then(res => res.json())
    .then(data => {
        const csrfToken = data.token;
        // 后续上传文件时携带Token
        const formData = new FormData();
        formData.append('file', document.querySelector('input[type=file]').files[0]);
        fetch('/upload', {
            method: 'POST',
            headers: {
                'X-CSRF-TOKEN': csrfToken
            },
            body: formData
        })
    });

3. 后端验证Token

后端在文件上传接口中,需要取出请求中的Token进行验证,验证通过才处理上传逻辑。以下是接口处理的示例:

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
    // 获取请求中的Token
    String clientToken = request.getParameter("csrf_token");
    // 如果是请求头传递的Token,用request.getHeader("X-CSRF-TOKEN")
    // 验证Token
    if (!CsrfTokenUtil.verifyToken(request, clientToken)) {
        return "请求非法,CSRF Token验证失败";
    }
    // Token验证通过,处理文件上传逻辑
    // 此处省略文件存储的具体代码
    return "文件上传成功";
}

防护注意事项

为了保证CSRF Token的防护效果,需要注意以下几点:

  • Token必须是随机生成、不可预测的,不要使用固定值或者容易被猜到的规则生成
  • Token要和用户的会话绑定,每个用户的Token独立,不要全局共用同一个Token
  • Token的有效期要合理,建议和用户会话有效期一致,或者单次使用后失效
  • 文件上传接口的Token验证要放在所有业务逻辑之前,避免未验证就处理请求
  • 对于支持跨域的文件上传接口,要配合CORS策略做限制,只允许可信的域名发起请求

常见问题解答

Token泄露会不会导致防护失效?

如果Token被攻击者通过XSS等方式获取,那么防护确实会失效,所以还需要配合XSS防护,对用户输入的内容做转义,避免Token被窃取。另外可以使用双重Cookie验证作为补充方案,进一步提升安全性。

文件上传用了验证码还需要CSRF Token吗?

验证码可以在一定程度上防范CSRF攻击,但是验证码会影响用户体验,而且如果验证码验证逻辑存在漏洞,还是可能被绕过。CSRF Token的防护更轻量,和验证码配合使用可以进一步提升安全性。

CSRF攻击文件上传CSRF_tokenWeb安全防护方案修改时间:2026-06-25 01:54:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。