如何分析Spring对CSRF的防范

这篇文章将为大家详细讲解有关如何分析Spring对CSRF的防范,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

坚守“ 做人真诚 · 做事靠谱 · 口碑至上 · 高效敬业 ”的价值观,专业网站建设服务10余年为成都不锈钢雕塑小微创业公司专业提供成都定制网站营销网站建设商城网站建设手机网站建设小程序网站建设网站改版,从内容策划、视觉设计、底层架构、网页布局、功能开发迭代于一体的高端网站建设服务。

什么是 CSRF

跨站请求伪造。经典场景是:

1)受害者首先登录了银行网站
2)用户没有 longout 的情况下
3)用同一个浏览器访问了“坏”网站
4)“坏”网站有一个向银行网站提交业务请求的页面
5)诱使用户发送这个请求。

实际上利用有 XSS 漏洞,完全可以无需受害者参与利用 javascript 而自动触发第 4 第 5 步。

这个场景背后的逻辑:

这里我们把浏览器等同于用户,有些数据是用户自己可见的,有些数据是浏览器自动处理、发送而用户对这些数据是无感知的(比如 SessionId)。
银行网站以 cookie 的形式把 sessionId 发送给浏览器(set-cookie),浏览器每次请求都会再自动带上 cookie(cookie)。
上面场景第 5 步虽然“坏”表单不是源于银行网站页面而是在第三方网站的页面上,但是浏览器发现目标地址是银行网站,因此会自动带上相应的 cookie,比如 JSESSION 就会随带着被发送了。从服务器的角度看,来自第 4 步的数据与正常数据没有任何差别,因为这个业务请求便会被执行。

归根结底,这种 CSRF 的问题是因为早期的cookie设计过于简单,没有和现代浏览器同源策略等安全机制同步造成的。

解决方案

一个是主流的“Synchronizer Token Pattern”方法,另一个是渐成主流的“SameSite Attribute”。

1)SameSite Attribute
这个方式实施和理解比较容易,我们先说。
服务端利用 cookie 的 SameSite 属性可以禁止浏览器从外部站点发送请求时带上 cookie。比如下面的 cookie 就不会被放在由在第三方网页发起而目标是银行网站的请求上。这就自然解决了上面的 CSRF 的问题。SameSite还可设为Strict。

Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax

2)Synchronizer Token Pattern
这个解决办法的原理是对来自浏览器的请求我们都回送一个随机数,下次浏览器再请求业务时需要在 header 里或者表单里带上这个随机数。这个随机数就是 csrf token。Spring Security就是采用的这个方式。
这个办法之所以能防范 CSRF,是因为 sessionId 来自 cookie,而 csrf token 来自 header 或者 form。相当于分别在两条不同的路径上传递

Spring Security 模块生成 csrf token 后可放在两个地方。Spring 默认的,随机数与 sessionId 关联,放在 session 里。另一个方式:随机数放在 cookie 里。

a) 基于 Session 保存 csrf token

与 session 关联比较容易理解,下次浏览器发送请求过来,服务端就可以从 header 或 form 里取出来的 csrf token 与 session 中的随机数相比较来进行判断。

b) 基于 Cookie 保存 csrf token

通过 cookie 保存 csrf 是怎么回事呢?如果 csrf token 通过 cookie 发送给浏览器,那这个随机数不就跟 JSESSIONID 一样了会被浏览器自动传回到服务器了吗?
是的,这个通过cookie传给浏览器的 csrf token 一定会被浏览器传回给服务器,我们也正是利用这一点“保存”了 csrf token。之所以使用基于 cookie 的方式,是因为要针对前后端分离的情形让前端可以使用 javascript 获得 csrf token,并把这个 token 作为下次请求的 header 参数或者 form 参数传递给服务端。服务端所要做的就是通过对比来自 cookie 和 header/form 这两条路径的 csrf token 来做出该请求是否为CSRF的判断。

下面代码设置使用 cookie 保存csrf token,使用 cookie 传递 token 需要把 cookie 的 HttpOnly 属性设置为 false,以便让 javascript 能读到此值。

@EnableWebSecuritypublic class WebSecurityConfig extends        WebSecurityConfigurerAdapter {
   @Override    protected void configure(HttpSecurity http) {        http            .csrf(csrf -> csrf                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())            );    }}

关于如何分析Spring对CSRF的防范就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


网站栏目:如何分析Spring对CSRF的防范
文章URL:http://myzitong.com/article/pooied.html