本文目录导读:

跨站请求伪造(CSRF)是一种常见的Web安全漏洞,攻击者诱导用户点击链接或访问页面,在用户不知情的情况下,利用用户已登录的身份向目标网站发送恶意请求(如转账、改密),要有效拦截CSRF攻击,通常采用以下后端防御策略(前端无法独立防御CSRF):
核心防御策略(推荐组合使用)
使用 Anti-CSRF Token(最常用、最有效)
- 原理:服务器为每个会话或每个表单生成一个随机、不可预测的Token,并将其嵌入到表单的隐藏字段或请求头中,服务器验证请求时,检查Token是否合法。
- 实现方式:
- 表单嵌入:在HTML表单中生成
<input type="hidden" name="_csrf_token" value="随机值">。 - 请求头携带:通过JavaScript从Cookie或页面变量中读取Token,附加到Ajax请求的
X-CSRF-Token或X-XSRF-TOKEN头中(常见于前后端分离项目,如Spring Security的默认实现)。
- 表单嵌入:在HTML表单中生成
- 关键点:Token必须与用户会话绑定,且攻击者无法伪造(不能通过跨域请求获取)。
- 注意:不要在GET请求中使用Token(GET请求可能被第三方网站直接触发),只对POST/PUT/DELETE等修改性请求进行验证。
同源检测(Origin / Referer 头验证)
- 原理:检查HTTP请求头中的
Origin(推荐)或Referer字段,判断请求是否来自本站(同源)。 - 实现:
- 验证
Origin头是否在允许的白名单中。Origin是安全头,由浏览器自动添加(仅跨域请求时)。 Origin为空(某些情况下,如HTTPS→HTTP请求可能丢失),可回退验证Referer。
- 验证
- 局限性:
Referer可能被用户隐私设置禁用,也可能由攻击者在某些漏洞下伪造(低概率)。Origin相对可靠,但某些旧浏览器不支持。
- 建议:作为辅助手段,与Token结合使用。
设置 SameSite Cookie 属性(浏览器原生防御)
- 原理:通过设置Cookie的
SameSite属性,控制浏览器在跨站请求时是否附带Cookie(默认不携带)。 - 属性值:
Strict(严格):所有跨站请求都不发送Cookie(最安全,但用户体验差,如从第三方网站点击链接到本站,Session丢失)。Lax(宽松,现代浏览器默认值):仅允许“顶级导航”GET请求(如点击链接、地址栏输入)发送Cookie,表单POST、Ajax等跨站请求不发送,这是平衡安全与体验的最佳选择。None:禁用SameSite防御,但必须同时设置Secure(仅HTTPS)。
- 用法(以Spring Boot为例):
response.addHeader("Set-Cookie", "JSESSIONID=xxx; SameSite=Lax; HttpOnly")。 - 注意:仅依靠SameSite还不够,因为有少数请求(如某些GET链接)仍可能携带Cookie,且旧浏览器不支持。
验证 HTTP 请求方法
- 原理:强制要求状态修改操作(增、删、改)使用POST、PUT、DELETE等安全方法,拒绝GET请求执行修改(因为攻击者容易构造
<img>或<a>标签触发GET)。 - 注意:不是防御CSRF的充分条件,但能消除大部分简单攻击向量。
二次验证(对高风险操作)
- 原理:对敏感操作(如修改密码、转账、删除账户)不依赖Token,强制用户输入当前密码、短信验证码或图形验证码。
- 效果:攻击者无法自动完成,极大提高难度。
- 适用场景:金融、账户管理等关键功能。
哪些方法“不能”拦截CSRF?
- 仅依赖前端(如JS防点击、验证Referer):攻击者可构造请求绕过前端。
- 使用Session在URL中传参:能被直接看到,且易泄露(如URL被分享到社交媒体)。
- 单纯依赖IP/UA/时间戳:这些信息可以被伪造或获取。
最佳实践组合(推荐)
对所有状态修改请求(POST/PUT/DELETE)生成并验证 Anti-CSRF Token(服务端会话绑定)。 2. 在全局过滤器/中间件中验证 Origin 头(或 Referer),作为第二道防线。 3. 将所有Session Cookie设置为 SameSite=Lax(或Strict),并 HttpOnly。 4. 拒绝GET请求做状态修改(RESTful规范遵循)。 5. 对高风险操作(如转账、改密)强制二次验证。
代码示例(简单Spring Boot防护)
生成Token(后端):
@RequestMapping("/form")
public String showForm(HttpServletRequest request, Model model) {
String csrfToken = UUID.randomUUID().toString();
request.getSession().setAttribute("CSRF_TOKEN", csrfToken);
model.addAttribute("csrfToken", csrfToken);
return "form";
}
验证Token(拦截器):
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if ("POST".equalsIgnoreCase(request.getMethod())) {
String sessionToken = (String) request.getSession().getAttribute("CSRF_TOKEN");
String requestToken = request.getParameter("_csrf_token");
if (sessionToken == null || !sessionToken.equals(requestToken)) {
response.sendError(403, "CSRF token mismatch");
return false;
}
}
return true;
}
- 最推荐:Anti-CSRF Token + SameSite=Lax + Origin验证,三者结合抵御绝大多数CSRF攻击。
- 核心思想:让攻击者无法伪造合法的请求凭证(Token)或无法附带关键身份凭证(Cookie)。
- 注意:CSRF防御是后端责任,前端只能辅助(如通过JS读取Cookie中的Token并添加到请求头),但不能作为唯一防线。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播