SpringSecurity框架下实现CSRF跨站攻击防御

一、什么是CSRF
很多朋友在学习Spring Security的时候,会将CORS(跨站资源共享)和CSRF(跨站请求伪造)弄混,以为二者是一回事。其实不是,先解释一下:
- CORS(跨站资源共享)是局部打破同源策略的限制,使在一定规则下HTTP请求可以突破浏览器限制,实现跨站访问。
- CSRF是一种网络攻击方式,也可以说是一种安全漏洞,这种安全漏洞在web开发中广泛存在。
当我们使用Spring Security的时候,这种CSRF漏洞默认的被防御掉了。但是你会发现在跨域请求的情况下,我们的POST、DELETE、PUT等HTTP请求方式失效了。所以在笔者之前的文章中,我们使用http.csrf.disable()暂时关闭掉了CSRF的防御功能,但是这样是不安全的,那么怎么样才是正确的做法呢?就是本文需要向大家介绍的内容。
二、CSRF的攻击方式
通常的CSRF攻击方式如下:
- 你登录了网站A,攻击者向你的网站A账户发送留言、伪造嵌入页面,带有危险操作链接。
- 当你在登录状态下点击了攻击者的连接,因此该链接对你网站A的账户进行了操作。
- 这个操作是你在网站A中主动发出的,并且也是针对网站A的HTTP链接请求,同源策略无法限制该请求。
三、如何防御CSRF攻击
- 为系统中的每一个连接请求加上一个token,这个token是随机的,服务端对该token进行验证。破坏者在留言或者伪造嵌入页面的时候,无法预先判断CSRF token的值是什么,所以当服务端校验CSRF token的时候也就无法通过。所以这种方法在一定程度上是靠谱的。
- 但是如果你的电脑中毒,网络信息被劫持使用token的方法仍然不安全。所以没有绝对的安全,道高一次魔高一丈。作为开发者,我们就做到我们应该做到的。
- 跳转提示:当用户不小心点击了第三方连接,合格的应用应该提示用户相关的风险!由用户自己确认是否真的要跳转或者执行第三方连接,或者就干脆不让非可信连接在留言区等地方存在。
四、Spring Security的CSRF token攻击防护
首先,我们要先开启防护功能,在用户登陆操作之后,生成的CSRF Token就保存在cookies中。
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.ignoringAntMatchers("/authentication");
.and()
...
}
}
- 使用CookieCsrfTokenRepository生成CSRF Token放入cookie,并设置cookie的HttpOnly=false,允许js读取该cookie。
- 使用ignoringAntMatchers开放一些不需要进行CSRF防护的访问路径,比如:登录授权。
至此,我们生成了CSRF token保存在了cookies中,浏览器向服务端发送的HTTP请求,都要将CSRF token带上,服务端校验通过才能正确的响应。这个校验的过程并不需要我们自己写代码实现,Spring Security会自动处理。但是我们需要关注前端代码,如何正确的携带CSRF token。
五、前端请求携带CSRF Token的方式
在thymeleaf模板中可以使用如下方式,在发送HTTP请求的时候携带CSRF Token。如果是前后端分离的应用,或者其他模板引擎,酌情从cookies中获取CSRF Toekn。
5.1.在Header中携带CSRF token
var headers = {};
headers['X-CSRF-TOKEN'] = "${_csrf.token}";
$.ajax({
headers: headers,
});
5.2.直接作为参数提交。
$.ajax({
data: {
"_csrf": "${_csrf.token}"
}
});
5.3.form表单的隐藏字段
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}">
期待您的关注
- 向您推荐博主的系列文档:《手摸手教您学习SpringBoot系列-16章97节》
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
SpringSecurity框架下实现CSRF跨站攻击防御的更多相关文章
- XSS/CSRF跨站攻击和防护方案
Xss(Cross Site Scripting 跨站脚本攻击)/CSRF(Cross-site request forgery 跨站请求伪造),它与著名的SQL注入攻击类似,都是利用了Web页面的编 ...
- SpringSecurity原理解析以及CSRF跨站请求伪造攻击
SpringSecurity SpringSecurity是一个基于Spring开发的非常强大的权限验证框架,其核心功能包括: 认证 (用户登录) 授权 (此用户能够做哪些事情) 攻击防护 (防止伪造 ...
- DDOS、CC、sql注入,跨站攻击防御方法
web安全常见攻击解读--DDos.cc.sql注入.xss.CSRF 一,DDos https://www.cnblogs.com/sochishun/p/7081739.html#4111858 ...
- XSS 与 CSRF 跨站攻击
先做个名词解释: XSS:跨站脚本(Cross-site scripting) CSRF:跨站请求伪造(Cross-site request forgery) 看了估计也不清楚什么意思吧? 那么,详细 ...
- SpringSecurity环境下配置CORS跨站资源共享规则
一.CORS简述 要说明CORS(Cross Origin Resourse-Sharing) 跨站资源共享,就必须先说同源策略.长话短说,同源策略就是向服务端发起请求的时候,以下三项必须与当前浏览器 ...
- Nancy启用跨站攻击防护(CSRF)
什么是CSRF(跨站攻击) 可能很多人已经对CSRF有所了解,就简单的介绍下: CSRF全程是 Cross-Site Request Forgery .大概意思就是在登录用户不知情的情况下,由一个网站 ...
- Django CBV装饰器 中间件 auth模块 CSRF跨站请求
CBV添加装饰器 给CBV添加装饰器有三种方法,三种方法都需要导入模块: from django.utils.decorators import method_decorator 第一种直接在方法上面 ...
- Laravel框架之CSRF防跨站攻击
laravel框架的csrf防跨站攻击,简单的意思就是说为了防止别人自己写表单非法提交,非法绕过前台的验证,直接将数据往后台执行. 一般的网站如果没有这些安全措施,比较容易被攻击.当然了也还要有其他的 ...
- Django框架(十二)-- 中间件、CSRF跨站请求伪造
中间件 一.什么是中间件 请求的时候需要先经过中间件才能到达django后端(urls,views,templates,models) 响应的时候也需要经过中间件才能到达web服务网关接口 djang ...
随机推荐
- 微服务SpringCloud之GateWay服务化和过滤器
Spring Cloud Gateway 提供了一种默认转发的能力,只要将 Spring Cloud Gateway 注册到服务中心,Spring Cloud Gateway 默认就会代理服务中心的所 ...
- 赤壁情:dp
首先这道题用到的3个新关键字大概讲一下: (我刚学会仅仅会瞎搞做题,欢迎大神补充) static:声明一个变量并清空.(不知道用不用时间,求解答) 具体用法:static 变量类型 变量名.如:sta ...
- [考试反思]0815NOIP模拟测试22
40分,15名. 1-4:120 75 70 70 35分20名...总之差距极小不想说了 昨天教练说:以后的考试还是联赛知识点,但是难度比联赛高. 没听进去,以为是对于所有人而言的,也就是T1难度变 ...
- [UWP]为番茄钟应用设计一个平平无奇的状态按钮
1. 为什么需要设计一个状态按钮 OnePomodoro应用里有个按钮用来控制计时器的启动/停止,本来这应该是一个包含"已启动"和"已停止"两种状态的按钮,但我 ...
- go xml 序列化
/** 序列化 */ package main import ( "encoding/xml" "fmt" ) // Person 结构 type Person ...
- 构建大型 Vue.js 项目的10条建议
下面是我在开发大型 Vue 项目时的最佳实践.这些技巧将帮助你开发更高效.更易于维护和共享的代码. 今年做自由职业的时候,我有机会开发了一些大型 Vue 应用程序.我所说的这些项目,Vuex stor ...
- mysql导入sql出错,无脑解决办法
找到my.cnf文件在[mysqld]的下面添加 sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTI ...
- Arduino 将 String 转化为 int
Arduino 将 String 转化为 int 函数:toInt() 实例: String my_str = "; int my_int = my_str.toInt();
- 结合Spring Security进行web应用会话安全管理
在本文中,将为大家说明如何结合Spring Security 和Spring Session管理web应用的会话. 一.Spring Security创建使用session的方法 Spring Sec ...
- 领扣(LeetCode)删除链表中的节点 个人题解
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点. 现有一个链表 -- head = [4,5,1,9],它可以表示为: 4 -> 5 -> 1 - ...