OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.15k stars 587 forks source link

Cookie paths in response quoted when LtpaToken2 cookie is set in same response #29528

Open otaconix opened 3 weeks ago

otaconix commented 3 weeks ago

Describe the bug

Path attributes of cookies set by JAX-RS resources somehow end up quoted when the request is authenticated (through HTTP Basic Auth) but does not yet contain an LtpaToken2 cookie.

This is problematic, as that leads browsers to ignore the path that the application attempted to set (since the quoted path is invalid), which leads to the browser defaulting to the "directory" of the requested URL. This in turn can result in the cookie not working for its intended purpose.

Steps to Reproduce

I've created a very simple application using the starter on openliberty.io. The application can be found here: https://github.com/otaconix/liberty-quoted-cookie-path-issue

  1. Run it with ./mvnw liberty:dev
  2. Fire a request at it with curl -i http://localhost:9080/app-name/api/ -u user:password

Just in case the repo ends up disappearing, I'll reproduce the server.xml and JAX-RS resource's code here:

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">
    <featureManager>
        <feature>jakartaee-10.0</feature>
        <feature>microProfile-6.1</feature>
    </featureManager>
    <basicRegistry id="basic" realm="BasicRealm">
        <user name="user" password="password" />
        <group name="ROLE">
            <member name="user"/>
        </group>
    </basicRegistry>
    <httpEndpoint id="defaultHttpEndpoint"
                  httpPort="9080"
                  httpsPort="9443" />
    <applicationManager autoExpand="true"/>
    <webApplication contextRoot="/app-name" location="app-name.war" />
    <ssl id="defaultSSLConfig" trustDefaultCerts="true" />
</server>
@Path("/")
@ApplicationScoped
public class RootResource {
    @RolesAllowed("ROLE")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response get() {
        return Response.ok("Check your cookies!")
                .cookie(new NewCookie.Builder("some-cookie")
                        .value("some-value")
                        .path("/")
                        .build())
                .build();
    }
}

Example output:

HTTP/1.1 200 OK
Content-Type: text/plain;charset=UTF-8
Content-Language: en-NL
Content-Length: 19
Set-Cookie: LtpaToken2=redacted; Path=/; HttpOnly
Set-Cookie: some-cookie=some-value; Version=1; Path="/"
Date: Thu, 29 Aug 2024 19:37:31 GMT
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Cache-Control: no-cache="set-cookie, set-cookie2"

Check your cookies!

Expected behavior
The "Path" attribute of the cookie named some-cookie should not be quoted.

Note that this issue does not occur when already logged in (replace <cookie-value-here> with the value from the response above):

$ curl -i http://localhost:9080/app-name/api/ -u user:password -H Cookie:LtpaToken2=<cookie-value-here>
HTTP/1.1 200 OK
Set-Cookie: some-cookie=some-value;Version=1;Path=/
Content-Type: text/plain;charset=UTF-8
Content-Language: en-NL
Content-Length: 19
Date: Thu, 29 Aug 2024 19:41:25 GMT
Expires: Thu, 01 Dec 1994 16:00:00 GMT
Cache-Control: no-cache="set-cookie, set-cookie2"

Check your cookies!

Diagnostic information:

otaconix commented 3 weeks ago

Just in case it's useful information: this seems to also affect tWAS 9.0.5 (the only version I've tested is 9.0.5.17).