You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@guacamole.apache.org by "Mike Brady (Jira)" <ji...@apache.org> on 2026/10/20 17:28:00 UTC

[jira] [Created] (GUACAMOLE-2345) RESTExceptionMapper invalidates the session of the first failed request instead of the current one

Mike Brady created GUACAMOLE-2345:
-------------------------------------

             Summary: RESTExceptionMapper invalidates the session of the first failed request instead of the current one
                 Key: GUACAMOLE-2345
                 URL: https://issues.apache.org/jira/browse/GUACAMOLE-2345
             Project: Guacamole
          Issue Type: Bug
          Components: guacamole
    Affects Versions: 1.6.0, 1.5.0, 1.4.0, 1.6.1 [staging]
            Reporter: Mike Brady



{{org.apache.guacamole.rest.RESTExceptionMapper}} is a {{@Singleton}} with

{code:java}
@Context
private ContainerRequest request;
{code}

Its comment says this object is always scoped to the current request, but {{ContainerRequest}} is a class, not an interface, so Jersey cannot inject a per-request proxy. The field keeps the first request for which the mapper was used (the first REST request that threw any exception after startup).

When a {{GuacamoleUnauthorizedException}} is mapped, the mapper destroys the session of {{getAuthenticationToken(request)}}, which is always that first request's token. This was introduced with GUACAMOLE-956 (commit 5fdfb56c8) and affects 1.4.0 through 1.6.x and current main.

h3. Effects

# After each restart, the first user whose REST request fails for any reason (e.g. a 404) is logged out later by any client, including an unauthenticated one, that sends an invalid or expired token. Once that token is destroyed, later attempts have no effect.
# The intended behaviour never happens: the session that triggered the unauthorized error is not invalidated, for example when an authentication extension rejects a session it considers expired.

This was first reported privately to security@; the PMC determined it is a bug rather than a vulnerability and asked for it to be handled through JIRA and a pull request.

h3. Steps to reproduce (default install, JDBC auth, two users A and B)

{noformat}
API=http://host:8080/guacamole/api
# restart Tomcat, then:
A=$(curl -s -d 'username=A&password=...' $API/tokens | jq -r .authToken)
B=$(curl -s -d 'username=B&password=...' $API/tokens | jq -r .authToken)
curl -s -o /dev/null -w '%{http_code}\n' "$API/session/data/postgresql/connections/999999?token=$A"  # 404, pins A's request
curl -s -o /dev/null -w '%{http_code}\n' "$API/session/data/postgresql/self?token=bogus"           # 403
curl -s -o /dev/null -w '%{http_code}\n' "$API/session/data/postgresql/self?token=$A"              # 403: A was logged out
curl -s -o /dev/null -w '%{http_code}\n' "$API/session/data/postgresql/self?token=$B"              # 200
{noformat}

With debug logging, step 2 logs {{Implicitly invalidated session for token "<A's token>"}}.

h3. Proposed fix

Retrieve the request through a provider each time:

{code:java}
@Context
private javax.inject.Provider<ContainerRequest> requestProvider;
...
authenticationService.getAuthenticationToken(requestProvider.get());
{code}

I will open a pull request with this change and a regression test (Jersey in memory via {{ApplicationHandler}}, no new dependencies; before the fix it fails with "expected [SECOND, THIRD] but was [FIRST, FIRST]").



--
This message was sent by Atlassian Jira
(v8.20.10#820010)