JBoss EAP 7 responds with an incorrect JSESSIONID Cookie when "HttpServletRequest#getRequestedSessionId()" is called in the application

Solution Unverified - Updated

Environment

  • Red Hat JBoss Enterprise Application Platform (EAP)
    • 7.x

Issue

When a client sends a request with a non-existent session id to a web application calling the Servlet API HttpServletRequest#getRequestedSessionId() (or HttpServletRequest#isRequestedSessionIdValid()), JBoss EAP 7 responds with an incorrect JSESSIONID response cookie as it reuses the requested non-existent session id instead of issuing a new JSESSIONID.

Resolution

  • This will be fixed in the future releases, tentatively EAP 7.1 CP3 (7.1.3) at this moment.
  • Until the fix is incorporated, a possible workaround is creating a servlet filter to override the two methods, HttpServletRequest#getRequestedSessionId() and HttpServletRequest#isRequestedSessionIdValid(). For example:
@WebFilter("/*")
public class WorkaroundFilter implements Filter {

    private static final String DEFAULT_SESSIONID_NAME = "JSESSIONID";

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res, FilterChain chain)
        throws IOException, ServletException {

        if (!(req instanceof HttpServletRequest)) {
            chain.doFilter(req, res);
            return;
        }

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request) {
            @Override
            public String getRequestedSessionId() {
                String sesionCookieName = request.getServletContext().getSessionCookieConfig().getName();
                if (sesionCookieName == null || sesionCookieName.isEmpty()) {
                    sesionCookieName = DEFAULT_SESSIONID_NAME;
                }
                if (request.isRequestedSessionIdFromCookie()) {
                    Cookie[] cookies = request.getCookies();
                    for (Cookie cookie: cookies) {
                        if (sesionCookieName.equals(cookie.getName())) {
                            String cookieValue = cookie.getValue();
                            if (cookieValue == null) {
                                return null;
                            }
                            int i = cookieValue.indexOf('.');
                            if(i > 0) {
                                return cookieValue.substring(0, i);
                            } else {
                                return cookieValue;
                            }
                        }
                    }
                }
                return null;
            }

            @Override
            public boolean isRequestedSessionIdValid() {
                HttpSession session = request.getSession(false);
                if (session == null) {
                    return false;
                }
                return session.getId().equals(getRequestedSessionId());
            }
        };

        chain.doFilter(wrappedRequest, res);
    }

    @Override
    public void destroy() {
    }

}

Root Cause

Components
Category

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.