Spring Security提供了两种机制来防止CSRF攻击:
- 同步器令牌模式(Synchronizer Token Pattern)
- 在会话cookie上指定SameSite属性
SameSite属性
防止CSRF攻击的一种新方法是在cookie上指定SameSite
属性。服务器可以在设置cookie时指定SameSite属性,以表明当来自外部站点时不应该发送cookie。
ℹ️ Spring Security不直接控制会话cookie的创建,因此它不提供对SameSite属性的支持。Spring Session在基于servlet的应用程序中提供对sameite属性的支持。Spring Framework的CookieWebSessionIdResolver为基于WebFlux的应用程序提供了对SameSite属性的开箱即用支持。
一个包含SameSite属性的http响应
Set-Cookie: JSESSIONID=randomid; Domain=bank.example.com; Secure; HttpOnly; SameSite=Lax
合法的SameSite
属性应为:
-
Strict
当指定时,来自同一站点的任何请求都会包含cookie。否则,cookie将不会包含在HTTP请求中。 -
Lax
当指定时,cookie将在来自相同站点或者请求来自顶层导航并且方法是幂等的时候发送。否则,cookie将不会包含在HTTP请求中
在会话cookie上设置了SameSite
属性后,浏览器将继续发送来自银行网站的请求的JSESSIONID
cookie。然而,浏览器将不再发送来自恶意网站的传输请求的JSESSIONID
cookie。由于会话不再出现在来自恶意网站的传输请求中,应用程序就可以免受CSRF攻击。
使用SameSite
需要注意的事项
将sameSite
属性设置为Strict
可以提供更强的防御,但可能会造成问题。假设一个用户登录了一个位于https://social.example.com的社交媒体网站。用户在https://email.example.org收到一封电子邮件,其中包含一个社交媒体网站的链接。如果用户点击了这个链接,他们就会理所当然地希望获得该社交媒体网站的身份验证。但是,如果``sameSite属性是
Strict`的,cookie将不会被发送,因此用户将不会被验证。
ℹ️我们可以通过实现gh-7537来提高SameSite保护对CSRF攻击的保护和可用性。
另一个明显的考虑是,为了让SameSite
属性保护用户,浏览器必须支持SameSite
属性。大多数现代浏览器都支持SameSite
属性。然而,仍在使用的旧浏览器可能不会。
出于这个原因,通常建议使用SameSite属性作为深度防御,而不是针对CSRF攻击的唯一保护。