mediumCVSS 6.5Vulnerability

GHSA-4hv6-xc92-j86g

### Summary Vikunja v2.6.0 introduced server-side sessions with revocation semantics: `DELETE /api/v2/user/sessions/{id}` documents "Revokes a specific session by its UUID", and enabling TOTP calls `DeleteAllUserSessions` to invalidate all sessions. The WebSocket endpoint accepts any cryptographically valid user JWT without ever resolving its `sid` (session id) claim against the sessions table. A connection authenticated before revocation stays authenticated and continues to receive live pushes indefinitely, and even brand-new WebSocket connections are accepted with a token whose session was deleted. The revocation feature therefore does not cover the WebSocket boundary at all. ### Details User access JWTs carry a session reference: `NewUserJWTAuthtoken` (`pkg/modules/auth/auth.go:188`) sets `claims["sid"] = sessionID`, and the API login-session documentation describes the claim as tying the JWT to a server-side session. On the HTTP side nothing consumes the claim per request either (REST access tokens simply expire after their short TTL, a design the maintainers documented when fixing GHSA-96q5, and refresh tokens are correctly invalidated when the session row is deleted). The WebSocket endpoint `GET /api/v2/ws` authenticates through the first client message. `Connection.handleAuth` (`pkg/websocket/connection.go:168`) validates the token exclusively with `auth.GetUserIDFromToken` (`pkg/modules/auth/auth.go:292`): ```go func GetUserIDFromToken(tokenString string) (int64, error) { token, err := jwt.Parse(tokenString, func(_ *jwt.Token) (any, error) { return []byte(config.ServiceSecret.GetString()), nil }) ... typ, ok := claims["type"].(float64) if !ok || int(typ) != AuthTypeUser { return 0, jwt.ErrTokenInvalidClaims } ... } ``` The function verifies signature and token type only. No session lookup occurs anywhere in the WebSocket path, and no re-validation happens after the initial auth. Consequently: 1. A connection authenticated before `DELETE /ap

Properties

severity
medium
summary
Vikunja: WebSocket authentication ignores server-side session state, so revoked sessions keep receiving live pushes
cvss_score
6.5
retrieved_at
2026-10-10T02:17:04+00:00
ghsa_published
2026-10-09T20:57:34Z
source_url
https://github.com/advisories/GHSA-4hv6-xc92-j86g
ghsa_updated
2026-10-09T20:57:35Z
ghsa_id
GHSA-4hv6-xc92-j86g
last_source
GitHub Advisory Database
cve_id
GHSA-4hv6-xc92-j86g
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
signal_observed_at
2026-10-10T02:17:04+00:00
is_ghsa_only
true

Related Entities (4)

VULNERABLE_TO (1)

←[Software]go/code.vikunja.io/api

AFFECTS (1)

→[Software]go/code.vikunja.io/api

HAS_WEAKNESS (1)

→[Weakness]Insufficient Session Expiration

REPORTED_BY (1)

→[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

GHSA-4hv6-xc92-j86g (CVSS 6.5) — Ninja Signal Threat Intelligence | Ninja Signal