SV.IL.SESSION.CLIENT

不应使用 HttpServletRequest.getRequestedSessionId 方法

使用 HttpServletRequest.getRequestedSessionId() 方法时,Klocwork 会报告 SV.IL.SESSION.CLIENT 缺陷。

漏洞与风险

根据 Oracle Java API,HttpServletRequest.getRequestedSessionId() 方法“返回客户端指定的会话 ID。该 ID 可能与此请求的当前有效会话 ID 不一样。如果客户端未指定会话 ID,则此方法将返回 null。”

该方法返回的会话 ID 通过 Cookie 或 URL 参数进行传输,因此根据定义,最终用户可以在 HTTP 请求中手动更新此会话 ID 的值。

以下示例为更新后的 HTTP 标头:

复制
GET /pageSomeWhere HTTP/1.1
Host: webSite.com
User-Agent: Mozilla/5.0
Cookie: JSESSIONID=Hacked_Session_Value'''">

由于最终用户可以手动更改该值,因此请求中的会话 ID 应该仅供 servlet 容器(例如 Tomcat 或 Jetty)使用,以查看该值是否与现有会话的 ID 相匹配。如果会话 ID 不匹配,则应将该用户视为未经身份验证。

缓解与预防

不要使用 HttpServletRequest.getRequestedSessionId 方法。而是在用户登录时生成新的会话 ID。

漏洞代码示例 1

复制
import javax.servlet.http.*;
import javax.servlet.*;
import java.security.*;
import java.io.*;
 
class Test{
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String id = request.getRequestedSessionId();
         if(authenticate(id)) {
           ...
         }
    }
}

Klocwork 在第 8 行报告了 SV.IL.SESSION.CLIENT 缺陷,指出“客户端提供的会话 ID 可以手动更改,从而更新 HttpRequest 中的此值。”