From 88be64c3db8d8272bf7dab9ba671b328946ff849 Mon Sep 17 00:00:00 2001 From: Lucas Coratger <73360179+coratgerl@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:19:25 +0100 Subject: [PATCH 1/2] feat(wabe): add tests for no reuse token after logout --- packages/wabe/src/security.test.ts | 42 ++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/wabe/src/security.test.ts b/packages/wabe/src/security.test.ts index c7ae931e..aa105292 100644 --- a/packages/wabe/src/security.test.ts +++ b/packages/wabe/src/security.test.ts @@ -580,6 +580,48 @@ describe('Security tests', () => { await closeTests(wabe) }) + it('should reject token reuse after logout', async () => { + const setup = await setupTests() + const wabe = setup.wabe + const port = setup.port + const rootClient = getGraphqlClient(port) + + const { userClient } = await createUserAndUpdateRole({ + anonymousClient: getAnonymousClient(port), + port, + roleName: 'Client', + rootClient, + }) + + const meBeforeLogout = await userClient.request(gql` + query me { + me { + user { + id + } + } + } + `) + + expect(meBeforeLogout.me.user).not.toBeNull() + + await userClient.request(graphql.signOut) + + const meAfterLogout = await userClient.request(gql` + query me { + me { + user { + id + } + } + } + `) + + expect(meAfterLogout.me.user).toBeNull() + + await closeTests(wabe) + }) + it('should throw an error if try to access to a class with empty authorizedRoles but not requireAuthentication', async () => { const setup = await setupTests([ { From 7106b6402f8b4fedf6e19758dba0c66052b1d678 Mon Sep 17 00:00:00 2001 From: Lucas Coratger <73360179+coratgerl@users.noreply.github.com> Date: Wed, 18 Feb 2026 20:22:38 +0100 Subject: [PATCH 2/2] feat: add test for fixation attacks --- packages/wabe/src/security.test.ts | 71 ++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/packages/wabe/src/security.test.ts b/packages/wabe/src/security.test.ts index aa105292..545106d6 100644 --- a/packages/wabe/src/security.test.ts +++ b/packages/wabe/src/security.test.ts @@ -622,6 +622,77 @@ describe('Security tests', () => { await closeTests(wabe) }) + it('should prevent session fixation by issuing new tokens on sign-in', async () => { + const setup = await setupTests() + const wabe = setup.wabe + const port = setup.port + const anonymousClient = getAnonymousClient(port) + + const userARes = await anonymousClient.request(graphql.signUpWith, { + input: { + authentication: { + emailPassword: { + email: 'attacker@test.fr', + password: 'password', + }, + }, + }, + }) + + const userBRes = await anonymousClient.request(graphql.signUpWith, { + input: { + authentication: { + emailPassword: { + email: 'victim@test.fr', + password: 'password', + }, + }, + }, + }) + + const tokenA = userARes.signUpWith.accessToken + const userIdA = userARes.signUpWith.id + const userIdB = userBRes.signUpWith.id + + const clientWithTokenA = getUserClient(port, { accessToken: tokenA }) + + await clientWithTokenA.request( + gql` + mutation signInWith($input: SignInWithInput!) { + signInWith(input: $input) { + accessToken + refreshToken + } + } + `, + { + input: { + authentication: { + emailPassword: { + email: 'victim@test.fr', + password: 'password', + }, + }, + }, + }, + ) + + const meWithTokenA = await clientWithTokenA.request(gql` + query me { + me { + user { + id + } + } + } + `) + + expect(meWithTokenA.me.user?.id).toBe(userIdA) + expect(meWithTokenA.me.user?.id).not.toBe(userIdB) + + await closeTests(wabe) + }) + it('should throw an error if try to access to a class with empty authorizedRoles but not requireAuthentication', async () => { const setup = await setupTests([ {