React SPA中同时抵御XSS与CSRF攻击的技术方案咨询
React SPA + 后端(如Go)的XSS与CSRF联合防护方案
核心矛盾
现代前端SPA场景下,HttpOnly Cookie能有效阻断XSS攻击窃取会话凭证,但完全依赖它会暴露在CSRF风险下;传统SSR场景的隐藏CSRF Token注入方案,又无法直接适配SPA的前端渲染模式。网上现有方案要么只覆盖SSR场景,要么只能单一防护XSS或CSRF,缺乏适合SPA的联合防护方案。
联合防护主方案:HttpOnly Cookie + 请求头CSRF Token
结合两种防护手段,具体流程如下:
- 登录流程:React渲染的登录页使用原生HTML表单提交登录请求,后端验证通过后,写入HttpOnly、Secure、SameSite=Strict/Lax的JWT Cookie,并重定向至SPA根路径触发重新渲染。
- 受保护资源请求前置:前端通过
fetch/axios请求受保护数据前,先发起一个无副作用的请求(如GET/api/csrf-token),后端通过HttpOnly JWT Cookie验证会话有效性后,返回一个临时CSRF Token。 - 资源请求:前端在后续的受保护请求中,同时携带HttpOnly JWT Cookie(浏览器自动携带)和自定义请求头(如
X-CSRF-Token),后端需同时验证Cookie的会话有效性和请求头中的CSRF Token合法性。
方案的潜在缺陷
获取CSRF Token的接口仅依赖HttpOnly Cookie做会话验证,若该接口未做额外防护(如限制请求来源、频率),攻击者可诱导用户访问恶意站点,触发该接口获取Token后发起CSRF攻击。但该方案的优势在于CSRF Token不在前端存储,避免了XSS窃取Token的风险。
替代方案及风险分析
方案1:CSRF Token存储在localStorage
- 实现方式:后端返回CSRF Token后,前端通过
localStorage.setItem('csrf-token', token)存储,请求时通过localStorage.getItem('csrf-token')获取并放入请求头。 - 风险:localStorage属于JS可访问的存储区域,一旦发生XSS攻击,Token会直接被窃取,完全失去CSRF防护的意义,安全性极低。
方案2:CSRF Token存储在前端JS环境(React Context/Redux)
- 实现方式:通过React的
createContext()创建全局的CSRFContext,或存入Redux状态中,请求时直接从状态中获取Token。 - 风险:虽比localStorage隐蔽,但仍属于JS可访问的内存区域,XSS攻击依然可以通过脚本读取Token,存在被窃取的风险;且需额外维护Token的生命周期(如过期刷新)。
内容的提问来源于stack exchange,提问作者Gilgamesh Skytrooper
相关产品推荐
相关产品推荐

