Phase 3 validated a stored ID token hint against the currently configured issuer, but the oversize path never got that check: an ID token above the 3.9KB cookie limit was stored as the bare string 'sso', which collapsed to an undefined hint at logout and skipped validation entirely. Changing the issuer while such a session was live bounced the user to the new IdP on logout. Stores sso.<base64url(issuer)> instead and moves all marker interpretation into buildEndSessionUrl: raw ID token -> iss/aud-validated hint, issuer-tagged marker -> round-trip without a hint, anything else -> no round-trip. Every branch fails closed. Refs #798.
This commit is contained in:
@@ -187,7 +187,7 @@ describe('OIDC logout-to-IdP (#798 phase 3)', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('stores a bare marker for oversized ID tokens; logout still round-trips, without a hint', async () => {
|
||||
it('stores an issuer-tagged marker for oversized ID tokens; logout still round-trips, without a hint', async () => {
|
||||
idp.setNextUser({
|
||||
sub: 'logout-sub-5',
|
||||
email: '[email protected]',
|
||||
@@ -198,7 +198,10 @@ describe('OIDC logout-to-IdP (#798 phase 3)', () => {
|
||||
const cbRes = await ssoRoundTrip();
|
||||
const cookie = idTokenCookie(cbRes);
|
||||
expect(cookie).toBeTruthy();
|
||||
expect(decodeURIComponent(cookie.replace('oidc_id_token=', ''))).toBe('sso');
|
||||
// Issuer-tagged marker, not the (oversized) token itself.
|
||||
const marker = decodeURIComponent(cookie.replace('oidc_id_token=', ''));
|
||||
expect(marker.startsWith('sso.')).toBe(true);
|
||||
expect(Buffer.from(marker.split('.')[1], 'base64url').toString('utf8')).toBe(idp.issuer);
|
||||
|
||||
const res = await request(app)
|
||||
.post('/api/auth/logout')
|
||||
@@ -210,6 +213,15 @@ describe('OIDC logout-to-IdP (#798 phase 3)', () => {
|
||||
expect(url.searchParams.get('client_id')).toBe(idp.clientId);
|
||||
});
|
||||
|
||||
it('skips the round-trip for an oversized-token marker from a DIFFERENT issuer', async () => {
|
||||
const foreignMarker = `sso.${Buffer.from('http://other-idp.example').toString('base64url')}`;
|
||||
const res = await request(app)
|
||||
.post('/api/auth/logout')
|
||||
.set('Cookie', `oidc_id_token=${foreignMarker}`)
|
||||
.expect(200);
|
||||
expect(res.body.ssoLogoutUrl).toBeUndefined();
|
||||
});
|
||||
|
||||
it('a fresh local-password login clears a stale SSO marker', async () => {
|
||||
const role = await db('roles').where({ name: 'admin' }).first();
|
||||
await db('admin_users').insert({
|
||||
|
||||
Reference in New Issue
Block a user