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)