You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为应用的所有GET请求启用CSRF保护?

嘿,这个问题问得很到位——很多人容易忽略GET请求的CSRF风险,但同时也容易踩URL暴露token的坑。先给你梳理下思路和解决方案:

核心前提:GET请求的CSRF防护必要性

首先得明确:HTTP规范定义GET是「安全且幂等」的方法,也就是它只应该用来获取资源、不应该执行任何修改系统状态的操作(比如提交数据、删除内容、修改配置)。如果你的GET请求只是做纯查询,其实不需要额外加CSRF防护——因为CSRF攻击的核心危害是攻击者诱导用户执行未授权的状态变更,纯查询操作即使被攻击,最多是泄露数据(那属于XSS或其他权限控制问题,不是CSRF的范畴)。

但如果你的GET请求确实涉及敏感操作(比如某些特殊场景下的状态变更,或者返回高度敏感的用户数据),那确实需要防护,接下来是安全的实现方式:

优先方案:重构HTTP方法,从根源规避风险

最稳妥的做法是把所有涉及状态变更的GET请求改成POST/PUT/DELETE这类非GET方法。这样不仅符合HTTP规范,还能直接复用你已经实现的POST请求CSRF防护逻辑,同时避免URL暴露token、浏览器缓存GET请求导致的误操作(比如用户误点书签触发敏感操作)。

必须保护GET时的安全传递方式

如果因为业务限制必须保留GET方法并加CSRF防护,那绝对不要把token放在URL参数里——URL会被浏览器缓存、存在历史记录、书签中,还可能被服务器日志记录,风险极高。推荐用以下方式:

自定义HTTP请求头传递token

在AJAX请求中添加一个自定义请求头(比如X-CSRF-Token),把token放在头里传递,这样不会出现在URL中,也不会被常规的日志或缓存记录。

修改你的AJAX代码如下:

$.ajax({
  url: "${pageContext.request.contextPath}/Someprocess.do",
  type: "GET",
  headers: { "X-CSRF-Token": "${CSRF_TOKEN}" }, // 把token放在请求头里
  data: {param1: request.param1, param2: "param2"},
  dataType: "json",
  success: function (data) { 
    response(data); 
  }
});

然后修改你的javax.servlet.Filter逻辑:

  • 对于GET请求,从HttpServletRequest.getHeader("X-CSRF-Token")获取token
  • 对比session中存储的token值,校验通过才允许请求继续
额外防护补充

给存储CSRF token的Cookie设置SameSite=Strict或SameSite=Lax属性,这样浏览器会限制跨站请求自动携带该Cookie,能大幅降低CSRF攻击的可能性。不过这只是辅助措施,不能替代token校验——因为同域内的恶意脚本(比如XSS注入的脚本)依然可以获取Cookie并添加到请求头里,所以还是要结合自定义头的token校验。

最后提醒
  • 不要在GET请求中执行任何写操作,这是HTTP设计的基本原则,也是避免CSRF风险的核心。
  • 确保你的CSRF token是每个用户会话唯一、不可预测的,并且过期后会重新生成,避免被复用。

内容的提问来源于stack exchange,提问作者Re Viki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 16:29:09