内容提要
CSRF(跨站请求伪造)利用浏览器自动携带Cookie的特性,诱骗已登录用户向目标网站发送伪造请求。攻击者无需窃取Cookie,只需诱导用户访问恶意网站,浏览器便会自动附带用户的会话凭证。防御措施包括CSRF令牌、SameSite Cookie、Origin/Referer校验等。Spring Security通过CsrfFilter实现防护,开发者应确保GET请求只读,并采用多层防御策略。
延伸解读
CSRF的本质:浏览器自动携带凭证
CSRF攻击的核心在于浏览器会自动为同域请求附加Cookie,而攻击者无需读取Cookie,只需诱导用户浏览器发送伪造请求。理解这一点有助于开发者认识到,单纯依赖CORS或Same Origin Policy无法防御CSRF,因为SOP只阻止跨域读取响应,不阻止发送请求。
SameSite=Lax的局限与防御纵深
现代浏览器默认SameSite=Lax,能阻止跨站POST等非安全方法的Cookie携带,但无法防御GET请求中的状态变更,且旧浏览器或特殊场景下可能失效。因此,SameSite应视为纵深防御的一部分,不能完全替代CSRF Token。
JWT存储方式决定CSRF风险
将JWT存储在localStorage中,由于浏览器不会自动附加,可免疫CSRF,但易受XSS攻击;而存储在HttpOnly Cookie中,虽防XSS,却重新引入CSRF风险。开发者需根据威胁模型权衡,并配合CSRF Token或SameSite属性。
Q&A
什么是CSRF攻击?
CSRF(跨站请求伪造)是一种攻击方式,攻击者利用浏览器自动携带Cookie的特性,诱骗已登录用户向目标网站发送伪造的、改变状态的请求。攻击者无需窃取Cookie,只需诱导用户访问恶意网站,浏览器便会自动附带用户的会话凭证,从而执行未授权的操作。
为什么浏览器会自动携带Cookie?
浏览器自动携带Cookie是为了实现无状态HTTP协议下的会话保持。当用户登录后,服务器通过Set-Cookie头设置会话ID,浏览器将其存储在Cookie Jar中,并在后续向同一域名的请求中自动附加Cookie,无需开发者或用户手动操作。
CSRF攻击是如何利用浏览器自动携带Cookie的?
攻击者在恶意网站(如evil.com)上放置一个自动提交的隐藏表单,目标指向用户已登录的网站(如travelbuddy.com)的敏感操作。当用户访问恶意网站时,浏览器会自动向目标网站发送请求,并自动附带用户的会话Cookie,服务器误以为这是用户本人的操作,从而执行攻击者指定的操作。
为什么同源策略(SOP)和CORS不能阻止CSRF?
同源策略(SOP)只限制跨域读取响应,不限制发送请求;CORS是用于放宽SOP的机制,允许跨域读取,但不会阻止请求的发送。CSRF攻击利用的是浏览器自动携带Cookie的机制,攻击者无需读取响应,只需触发请求即可,因此SOP和CORS无法防御CSRF。
CSRF令牌(Synchronizer Token Pattern)是如何工作的?
服务器在用户会话中生成一个随机的CSRF令牌,并将其嵌入到表单或页面中。当用户提交请求时,浏览器会携带该令牌,服务器验证令牌是否与会话中的值匹配。如果匹配则请求有效,否则拒绝。由于攻击者无法读取或猜测令牌,因此无法伪造有效请求。
SameSite Cookie属性如何帮助防御CSRF?
SameSite属性可以控制浏览器在跨站请求时是否携带Cookie。设置为Strict时,所有跨站请求都不携带Cookie;设置为Lax时,仅允许安全的GET请求在跨站导航时携带Cookie,而跨站POST等请求则不会携带。这可以有效阻止CSRF攻击,因为攻击者发起的跨站请求不会携带用户的会话凭证。
Spring Security如何实现CSRF防护?
Spring Security通过CsrfFilter实现CSRF防护。默认情况下,它会为每个会话生成一个CSRF令牌,并在表单或请求头中要求携带。对于非安全方法(如POST、PUT、DELETE),Spring Security会验证令牌,如果缺失或不匹配则返回403错误。开发者可以通过配置启用或禁用CSRF保护。
使用JWT时如何避免CSRF攻击?
如果JWT存储在localStorage或sessionStorage中,并通过Authorization头发送,则不会自动携带,因此不受CSRF影响,但需防范XSS。如果JWT存储在HttpOnly Cookie中,则浏览器会自动携带,此时需要结合CSRF令牌或SameSite属性进行防护。
什么是登录CSRF(Login CSRF)?
登录CSRF是一种攻击,攻击者诱导受害者的浏览器登录到攻击者的账户,从而窃取受害者在攻击者账户中输入的数据。OAuth 2.0中的state参数可以防止这种攻击,因为它作为CSRF令牌,确保回调请求与用户发起的登录流程匹配。