SV.CSRF.GET

此错误表明可能存在通过请求的 URL 泄漏跨站点请求伪造令牌的情况。

漏洞与风险

跨站点请求伪造 (CSRF) 是一种发生在以下情况下的攻击类型:恶意网站、电子邮件、博客、即时消息或程序导致用户的 Web 浏览器在用户当前经过身份验证的受信任站点上执行并非所需的操作。

减轻 CSRF 漏洞造成的危害的标准方法是使用同步程序令牌。经加密的安全随机令牌仅与用户会话相关联,可作为隐藏字段添加到任何导致状态变化操作的表单中。如果 CSRF 令牌验证失败,服务器会拒绝所请求的操作。

各种同步程序令牌实施包括 GET (URL) 请求以及 POST 请求中的质询令牌。尽管该控制的确可以帮助减轻 CSRF 攻击的风险,但每个会话的唯一令牌会暴露给 GET 请求。GET 请求中的 CSRF 令牌可能会在多个位置发生泄漏。

代码示例

漏洞代码示例 1

复制
   void doGet(HttpServletRequest req, HttpServletResponse resp) {
   if (!isValidRequest(req)) {
       handleInvalidRequest(req, resp);
   } else {
       update(req, resp);
   }
 }

   private boolean isValidRequest(final HttpServletRequest req) {
        return req.getParameter("_csrf_token").equals(req.getSession().getAttribute("_csrf_token"));
   }

   private void update(HttpServletRequest req, HttpServletResponse resp) {
       //...
   }

   private void handleInvalidRequest(HttpServletRequest req, HttpServletResponse resp) {
       //...
   }

在第 16 行报告了 SV.CSRF.GET:正在对 req 进行 CSRF 令牌检查(在第 25 行)。GET 请求不应用于状态变化操作,因此 CSRF 检查并非必需。CSRF 令牌检查可表明 GET 请求中存在该令牌,因而可能通过 URL 泄漏。

修正代码示例 1

复制
   void doPost(HttpServletRequest req, HttpServletResponse resp) {
   if (!isValidRequest(req)) {
       handleInvalidRequest(req, resp);
   } else {
       update(req, resp);
   }
 }

   private boolean isValidRequest(final HttpServletRequest req) {
        return req.getParameter("_csrf_token").equals(req.getSession().getAttribute("_csrf_token"));
   }

   private void update(HttpServletRequest req, HttpServletResponse resp) {
       //...
   }

   private void handleInvalidRequest(HttpServletRequest req, HttpServletResponse resp) {
       //...
   }

理想的解决方案是仅将 CSRF 令牌包括在 POST/PUT/DELETE 请求中,并将具有状态变化影响的服务器端操作更改为仅响应 POST/PUT/DELETE 请求。这实际上也是 RFC 2616 对 GET 请求的要求。如果确保敏感服务器端操作仅响应 POST/PUT/DELETE 请求,则无需将令牌包括在 GET 请求中。

安全培训

应用程序安全培训材料由 Secure Code Warrior 提供。

扩展

此检查器可通过 Klocwork 知识库进行扩展。有关详情,请参阅调整 Java 分析。