| CVE | Icon | Vulnerability name | Date | Responsible Security Disclosure by | Stars | Process | Vulnerabilities |
|---|---|---|---|---|---|---|---|
| - | CasTokenBleed | 2026-10-02 | xet7 | Found while auditing the CAS login callback after the 2026-10-02 Hall of Fame review; fixed by xet7. | The CAS callback stored the identity CAS had validated under whatever The browser that starts a CAS login now sets a cookie with its token, and the callback is accepted only when that cookie matches. A ticket parameter on an instance without CAS is left to its route. CWE-352: login cross-site request forgery leading to account takeover. Critical severity where CAS is enabled. No CVE assigned. Fix prepared locally for the Upcoming release; not yet released. |
A CAS login starts in the browser, which makes up a casToken and sends the user to the CAS server with a service URL that carries it. CAS sends the user back with a ticket; WeKan validates the ticket and stores the identity CAS returned under that token, and the browser then logs in with cas: { credentialToken }.
Nothing tied the token to the browser that made it up. An attacker could choose a token, send a victim who was already signed in to CAS a link to the CAS login page whose service parameter is WeKan's own address with ?casToken=KNOWN added, and wait. CAS sent the victim straight back with a ticket for their own account, WeKan stored the victim's identity under KNOWN, and the attacker logged in with cas: { credentialToken: 'KNOWN' } as the victim.
This is a different fault from CasRaceBleed, the concurrent-login race reported by meifukun, which mixed up two genuine logins; here the attacker starts no login of their own at the CAS server.
The browser that starts a CAS login sets a SameSite=Lax cookie holding its token, and the callback stores an identity only when the token in the URL matches that cookie, which a link sent to somebody else cannot carry. A ticket parameter on an instance without CAS is left to the route it was meant for.
A callback whose token the browser did not set is refused and summarized as CasTokenBleed in Admin Panel → Problems (catalog key authn.cas-state, recorded through the cas.state-mismatch canary).
Unit tests in tests/casStateBinding.test.cjs check that the state is read only from its own cookie, reproduce the reported attack - a callback whose token this browser did not set is refused and recorded - and the negative test fails unless the browser that starts a login sets the state it will be checked against. The unit tests pass in the WeKan repository. A login against a real CAS server was not tested.