Graylog2 / Graylog2/graylog2-server
Trusted Header Authentication: stale/expired `authentication` cookie blocks fallback to header auth on `/api/system/sessions`
- Dominant language
- Java
- Stars
- 8.1k
- Forks
- 1.1k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 217
Description
## Description
When using Trusted Header Authentication behind a reverse proxy, `GET /api/system/sessions` correctly creates a session from the trusted header **when no `authentication` cookie is present** (fixed in #9403 / #9404). However, if an **expired or otherwise invalid** `authentication` cookie is still sent by the browser, that endpoint returns `is_valid: false` and does **not** fall back to the trusted header, even though the header is valid and every other API endpoint authenticates successfully via it in the same request.
Since the web frontend uses `GET /api/system/sessions` on load to determine whether the user is logged in, this causes the login page to reappear every time the Graylog session cookie expires (default `Max-Age` ~8h) — even though the user is still fully authenticated via the trusted header for every other request. The user is forced to manually clear the `authentication` cookie to get a fresh session.
## Steps to reproduce
With Trusted Header Authentication enabled (`username_header: X-Forwarded-User`) and a reverse proxy passing that header:
```bash
# 1. Fresh request, no cookie — header auth creates a session as expected
curl -H 'X-Forwarded-User: someuser' http://graylog:9000/api/system/sessions
# => {"session_id":"...","username":"someuser","is_valid":true}
# (also sets a new `authentication` cookie via Set-Cookie)
# 2. Same header, but with a stale/invalid `authentication` cookie attached
curl -H 'X-Forwarded-User: someuser' \
-H 'Cookie: authentication=00000000-0000-0000-0000-000000000000' \
http://graylog:9000/api/system/sessions
# => {"session_id":null,"username":null,"is_valid":false}
```
## Expected behavior
When the `authentication` cookie is present but invalid/expired, `/api/system/sessions` should behave the same as when no cookie is present at all: fall back to the trusted header and create a fresh session (matching the fix already made in #9403 for the "no cookie" case).
## Actual behavior
The stale cookie takes precedence and short-circuits the check before the trusted header realm is consulted, returning `is_valid: false`.
## Environment
- Graylog Server: 7.0.11 (Open)
- Auth: Trusted Header Authentication (`org.graylog2.security.headerauth.HTTPHeaderAuthConfig`), header `X-Forwarded-User` set by oauth2-proxy behind Traefik
- `trusted_proxies` correctly configured in `server.conf`, confirmed via access logs that every request (including the failing `/api/system/sessions` calls) is attributed to the correct authenticated username
## Additional context
This looks closely related to #9403 / the fix in #9404 ("Create session when user can be authenticated based on trusted header"), which explicitly handles the *no session exists yet* case. This report covers the adjacent *stale/invalid session exists* case, which doesn't appear to be covered by that fix.
Contributor guide
Research direction
Start by tracing the GET /api/system/sessions entry point and the authentication cookie validation, then compare its behavior with the trusted-header path from #9403/#9404 and org.graylog2.security.headerauth.HTTPHeaderAuthConfig. Done means an expired or invalid authentication cookie no longer prevents valid X-Forwarded-User authentication, while the no-cookie behavior remains unchanged; verify both curl scenarios from the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, authentication, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100