Opencast: Session fixation enables account takeover via a crafted link
An attacker sets a chosen session id in the victim's browser through a crafted link; because Opencast does not rotate the id on login, the attacker rides the victim's session after the victim logs in, up to full administrator control.
Advisory ID: TP-2026-048
Product: Opencast (open-source system for capturing, managing, and delivering lecture and video content)
Vulnerability type: Session fixation (CWE-384)
CVE: CVE-2026-77614
CVSS 3.1: 8.8 (High) · CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
Vendor advisory: GHSA-6f53-jp7x-gg7p
Affected versions: opencast < 19.7 and < 20.2 (verified on 20.0, Docker allinone)
Fixed in: 19.7, 20.2
Reported: 17 June 2026
Summary
Opencast is an open-source system for capturing, managing, and delivering lecture and video content. The application does not renew the session id JSESSIONID on login and additionally accepts a client-supplied id from the URL path parameter ;jsessionid=, which the server reflects back as a Set-Cookie in the victim's browser. An attacker sends the victim a link carrying a chosen id; once the victim logs in through that browser, that exact id stays bound to the authenticated session. The attacker reuses the same id with no credentials and rides the victim's session, and for an administrator this means full control of the tenant. turingpoint verified the chain live against a running Opencast instance (default 20.0) and reported it to the vendor, which fixed it in 19.7 and 20.2.
Root cause
The <sec:http create-session="ifRequired"> block in etc/security/mh_default_org.xml:21 ships with no <sec:session-management> element at all, so no session id rotation takes place. Authentication runs through a custom CompositeFilter chain plus <sec:form-login> (mh_default_org.xml:396), so the namespace SessionFixationProtectionStrategy (migrateSession) is not applied. The custom success handler AuthenticationSuccessHandler.onAuthenticationSuccess (modules/kernel/src/main/java/org/opencastproject/kernel/security/AuthenticationSuccessHandler.java:74) calls request.getSession() but no changeSessionId() or invalidate(). The embedded Jetty/pax-web has jsessionid URL tracking enabled, accepts an id supplied via ;jsessionid=, and returns it as Set-Cookie: JSESSIONID=…. The JSESSIONID cookie carries neither Secure nor SameSite, and there is no CSP, so a cross-site link can set the id over plain HTTP.
Proof of Concept
# 1. Victim clicks a link that sets an attacker-chosen session id:
GET /admin-ui/index.html;jsessionid=ATTACKERVALUE.node0
# -> 302 Set-Cookie: JSESSIONID=ATTACKERVALUE.node0; Path=/; HttpOnly
# 2. Victim logs in as administrator in that browser (id is not rotated):
POST /j_spring_security_check (admin:opencast, cookie JSESSIONID=ATTACKERVALUE.node0)
# 3. Attacker reuses the same id with no credentials:
GET /info/me.json Cookie: JSESSIONID=ATTACKERVALUE.node0
# -> {"user":{"username":"admin"}, "roles":[ROLE_ADMIN,ROLE_SUDO,ROLE_USER_ADMIN,...]}
The server binds the attacker-supplied id and does not renew it on login, so the pre-login and post-login ids stay identical. Because JSESSIONID alone keys the session, the attacker then reaches /info/me.json and /admin-ng/users/users.json as the logged-in administrator using the same id.
Impact
- Full takeover of any account whose holder follows the crafted link and then logs in, including administrators (
ROLE_ADMIN/ROLE_SUDO). - Full control of the Opencast tenant: user management, all media and series, and configuration.
- Exploitation without credentials, without XSS, and without MITM; a clicked link plus a later login is enough.
- Aggravated by the missing
SecureandSameSiteattributes on theJSESSIONIDcookie and the absent CSP.
References
Is Something Like This in Your Software?
Our team found this vulnerability in the course of its work. Have your applications reviewed by the same specialists, with a penetration test from turingpoint.
