Uploaded image for project: 'WildFly'
  1. WildFly
  2. WFLY-10262

CodecSessionConfig#findSessionId() can cause an incorrect JSESSIONID response cookie reusing a requested non-existent session id

    Details

    • Steps to Reproduce:
      Hide
      1. Start WildFly (this issue happens with both standalone.xml and standalone-ha.xml)
      2. Deploy a web app having the following JSP:

        <%
        out.println("request.getRequestedSessionId() = " + request.getRequestedSessionId());
        out.println("request.isRequestedSessionIdValid() = " + request.isRequestedSessionIdValid());
        out.println("session.getId() = " + session.getId());
        %>
        

      3. Send a request to the JSP with a non-existent session id like:

        $ curl -v -H "Cookie: JSESSIONID=test" http://localhost:8080/test/example.jsp
        

      Show
      Start WildFly (this issue happens with both standalone.xml and standalone-ha.xml) Deploy a web app having the following JSP: <% out.println("request.getRequestedSessionId() = " + request.getRequestedSessionId()); out.println("request.isRequestedSessionIdValid() = " + request.isRequestedSessionIdValid()); out.println("session.getId() = " + session.getId()); %> Send a request to the JSP with a non-existent session id like: $ curl -v -H "Cookie: JSESSIONID=test" http://localhost:8080/test/example.jsp

      Description

      When a client sends a request with a non-existent session id to a web application calling "HttpServletRequest#getRequestedSessionId()" or "HttpServletRequest#isRequestedSessionIdValid()", WildFly responds with an incorrect JSESSIONID response cookie reusing the requested non-existent session id even though a new session id is internally generated.

      a simple reproducer

      <%
      out.println("request.getRequestedSessionId() = " + request.getRequestedSessionId());
      out.println("request.isRequestedSessionIdValid() = " + request.isRequestedSessionIdValid());
      out.println("session.getId() = " + session.getId());
      %>
      

      The following is an example result. WildFly should not respond with "Set-Cookie: JSESSIONID=test.node1" but should respond with a new session id like "Set-Cookie: JSESSIONID=brzJWBXpBnUZelcwnI9HCEbw9X6d0oQ5PypfiwML.node1" in this case.

      $ curl -v http://node1:8080/test/example.jsp -H "Cookie: JSESSIONID=test"
      ...
      > GET /test/example.jsp HTTP/1.1
      > User-Agent: curl/7.29.0
      > Host: node1:8080
      > Accept: */*
      > Cookie: JSESSIONID=test
      >
      < HTTP/1.1 200 OK
      < Connection: keep-alive
      < X-Powered-By: JSP/2.3
      < Set-Cookie: JSESSIONID=test.node1; path=/test
      < Content-Type: text/html;charset=ISO-8859-1
      < Content-Length: 143
      < Date: Wed, 18 Apr 2018 17:11:58 GMT
      <
      request.getRequestedSessionId() = test
      request.isRequestedSessionIdValid() = false
      session.getId() = brzJWBXpBnUZelcwnI9HCEbw9X6d0oQ5PypfiwML
      

      WildFly "CodecSessionConfig#findSessionId()" is invoked from Undertow "HttpServletRequestImpl#getRequestedSessionId() and isRequestedSessionIdValid()" to obtain the request session id.

      In "CodecSessionConfig#findSessionId()", WildFly checks if the reencoded session id is changed or not (= if an instance-id /jvmRoute information is changed or not), then invokes "this.config.setSessionId(exchange, reencodedSessionId)" to reset session id. Encoding a non-existent session always results in the different reencoded session id, therefore "this.config.setSessionId(exchange, reencodedSessionId)" is always invoked and this issue happens in this scenario.

      Undertow - servlet/src/main/java/io/undertow/servlet/spec/HttpServletRequestImpl.java

       349     @Override
       350     public String getRequestedSessionId() {
       351         SessionConfig config = originalServletContext.getSessionConfig();
       352         if(config instanceof ServletContextImpl.ServletContextSessionConfig) {
       353             return ((ServletContextImpl.ServletContextSessionConfig)config).getDelegate().findSessionId(exchange);
       354         }
       355         return config.findSessionId(exchange);
       356     }
        :
       421     @Override
       422     public boolean isRequestedSessionIdValid() {
       423         HttpSessionImpl session = servletContext.getSession(originalServletContext, exchange, false);
       424         if(session == null) {
       425             return false;
       426         }
       427         if(session.isInvalid()) {
       428             return false;
       429         }
       430         return session.getId().equals(getRequestedSessionId());
       431     }
      

      WildFly - undertow/src/main/java/org/wildfly/extension/undertow/session/CodecSessionConfig.java

       54     @Override
       55     public String findSessionId(HttpServerExchange exchange) {
       56         String encodedSessionId = this.config.findSessionId(exchange);
       57         if (encodedSessionId == null) return null;
       58         String sessionId = this.codec.decode(encodedSessionId);
       59         // Check if the encoding for this session has changed
       60         String reencodedSessionId = this.codec.encode(sessionId);
       61         if (!reencodedSessionId.equals(encodedSessionId)) {
       62             this.config.setSessionId(exchange, reencodedSessionId);
       63         }
       64         return sessionId;
       65     }
      

        Gliffy Diagrams

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  swd847 Stuart Douglas
                  Reporter:
                  mmiura Masafumi Miura
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: