Search code examples
javacookiesjettyembedded-jettycookie-httponly

Jetty - httponly cookie not being saved in browser in embedded jetty 11


In my web app i am setting response cookies this way:

Cookie testCookie = new Cookie("test", "mycookie");
testCookie.setHttpOnly(true);
testCookie.setPath("/");
testCookie.setMaxAge(3600);
testCookie.setSecure(true);

response.addCookie(testCookie); // Response is of type HttpServletResponse

The client that is performing the requests is running in localhost.

When i look at the request in chrome, i see that cookie tab and see that the cookie was received but I cannot find this cookie in chrome when i look in the Application->Cookies tab and the other requests i do after this was done, do not send cookies.

Also, in jetty 11 i cannot seem to be able to set the SameSite attribute of the cookie.

How can i set this cookie and is it normal that an httpOnly cookie is not visible in the Application tab in chrome? How can i verify if it was set or not?

EDIT: Additional details I am running the client in https://localhost and the server is using https with a self signed certificate. The cookie i am receiving seems corect from the response but then chrome does not seem to save it.


Solution

  • Our experience is that Chrome will reject/drop any Set-Cookie without a SameSite value set.

    The behavior in Jetty 11 ...

    • jakarta.servlet.http.Cookie has no setters/getters for "SameSite" (that's a feature of the next Servlet API release).
    • By default, the ServletContext attribute org.eclipse.jetty.cookie.sameSiteDefault contains the default value for the SameSite cookie attribute. (use one of value None, Strict, or Lax). If this attribute is unset there is no SameSite value provided with your cookies.
    • You can configure SameSite, and HttpOnly with cookie comments in Jetty to control specific Cookie SameSite behavior.

    Example:

    Cookie testCookie = new Cookie("test", "mycookie");
    testCookie.setHttpOnly(true);
    testCookie.setPath("/");
    testCookie.setMaxAge(3600);
    testCookie.setSecure(true);
    testCookie.setComment("__SAME_SITE_LAX__");
    // This can be __SAME_SITE_NONE__, or __SAME_SITE_STRICT__, or __SAME_SITE_LAX__
    
    response.addCookie(testCookie);
    

    When evaluating these changes in your browser, confirm that the Set-Cookie response header is what you want first, then look at the application tab.

    Note that Chrome has tons of special rules for domain names that are IP addresses, single label domains, and reserved hostnames such as "test" or "localhost", etc. These do not work normally for TLS/SSL, SameSite, CORs, Preflight requests, etc. Avoid using any of these while you are testing, use a fully qualified hostname when you can, otherwise you'll be surprised by these rules.