Spring Security 如何预防CSRF跨域攻击?( 二 )


<form method="post"    action="/transfer"><input type="hidden"    name="_csrf"    value="4bfd1575-3ad1-4d21-96c7-4ef2d9f86721"/><input type="text"    name="amount"/><input type="text"    name="routingNumber"/><input type="hidden"    name="account"/><input type="submit"    value=https://www.isolves.com/it/wl/aq/2021-01-15/"Transfer"/>现在,该表单包含具有CSRF令牌值的隐藏输入 。
外部站点无法读取CSRF令牌,因为相同的来源策略可确保恶意站点无法读取响应 。
相应的HTTP汇款请求如下所示:
POST /transfer HTTP/1.1Host: bank.example.comCookie: JSESSIONID=randomidContent-Type: application/x-www-form-urlencodedamount=100.00&routingNumber=1234&account=9876&_csrf=4bfd1575-3ad1-4d21-96c7-4ef2d9f86721您会注意到,HTTP请求现在包含带有安全随机值的_csrf参数 。
恶意网站将无法为_csrf参数提供正确的值(必须在邪恶网站上明确提供),并且当服务器将实际CSRF令牌与预期CSRF令牌进行比较时,传输将失败 。
SameSite属性防止CSRF攻击的一种新兴方法是在cookie上指定SameSite属性 。
设置cookie时,服务器可以指定SameSite属性,以指示从外部站点发出时不应发送该cookie 。

Spring Security 如何预防CSRF跨域攻击?

文章插图
 
Spring Security不直接控制会话cookie的创建,因此它不提供对SameSite属性的支持 。
Spring Session在基于servlet的应用程序中为SameSite属性提供支持 。
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请求中 。
真实案例让我们看一下如何使用SameSite属性保护我们的示例 。
银行应用程序可以通过在会话cookie上指定SameSite属性来防御CSRF 。
在会话cookie上设置SameSite属性后,浏览器将继续发送JSESSIONID cookie和来自银行网站的请求 。但是,浏览器将不再发送带有来自邪恶网站的传输请求的JSESSIONID cookie 。由于会话不再存在于来自邪恶网站的传输请求中,因此可以保护应用程序免受CSRF攻击 。
注意范围使用SameSite属性防御CSRF攻击时,应注意一些重要注意事项 。
(1)将SameSite属性设置为Strict可以提供更强的防御能力,但会使用户感到困惑 。
考虑一个保持登录到托管在https://social.example.com上的社交媒体网站的用户 。用户在https://email.example.org上收到一封电子邮件,其中包含指向社交媒体网站的链接 。
如果用户单击链接,则他们理所当然地希望能够通过社交媒体站点进行身份验证 。
但是,如果SameSite属性为Strict,则不会发送cookie,因此不会对用户进行身份验证 。
另一个明显的考虑因素是,为了使SameSite属性能够保护用户,浏览器必须支持SameSite属性 。
(2)大多数现代浏览器都支持SameSite属性 。
但是,可能仍未使用较旧的浏览器 。
因此,通常建议将SameSite属性用作深度防御,而不是针对CSRF攻击的唯一防护 。
何时使用CSRF保护什么时候应该使用CSRF保护?
我们的建议是对普通用户可能由浏览器处理的任何请求使用CSRF保护 。
如果仅创建非浏览器客户端使用的服务,则可能需要禁用CSRF保护 。
CSRF保护和JSON一个常见的问题是“我需要保护由JavaScript发出的JSON请求吗?”
简短的答案是,这看情况 。
但是,您必须非常小心,因为有些CSRF漏洞会影响JSON请求 。
例子例如,恶意用户可以使用以下格式使用JSON创建CSRF:
<form action="https://bank.example.com/transfer" method="post" enctype="text/plain">    <input name='{"amount":100,"routingNumber":"evilsRoutingNumber","account":"evilsAccountNumber", "ignore_me":"' value=https://www.isolves.com/it/wl/aq/2021-01-15/'test"}' type='hidden'>


推荐阅读