From 6a58bdf17790a1c50ce7d3fa42ec63c6dedd86f5 Mon Sep 17 00:00:00 2001 From: Mihaly Lengyel Date: Fri, 22 Nov 2024 13:52:07 +0100 Subject: [PATCH] fix: validate MFA claim before allowing TOTP device removal --- CHANGELOG.md | 1 + lib/build/recipe/totp/api/removeDevice.js | 6 +++++- lib/ts/recipe/totp/api/removeDevice.ts | 6 +++++- test/test-server/src/testFunctionMapper.ts | 10 ++++++++++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3c5f36c4..ddef785a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Adds `getCookieNameForTokenType` config option to allow customizing the cookie name for a token type. - Adds `getResponseHeaderNameForTokenType` config option to allow customizing the response header name for a token type. - Please note, that using this will require further customizations on the frontend +- Fixes an issue where `removeDevice` API allowed removing TOTP devices without the user completing MFA. ## [21.0.0] - 2024-10-07 diff --git a/lib/build/recipe/totp/api/removeDevice.js b/lib/build/recipe/totp/api/removeDevice.js index 3893442a1..b2dbd4a38 100644 --- a/lib/build/recipe/totp/api/removeDevice.js +++ b/lib/build/recipe/totp/api/removeDevice.js @@ -28,7 +28,11 @@ async function removeDeviceAPI(apiImplementation, options, userContext) { const session = await session_1.default.getSession( options.req, options.res, - { overrideGlobalClaimValidators: () => [], sessionRequired: true }, + { + overrideGlobalClaimValidators: (globalClaimValidators) => + globalClaimValidators.filter((v) => v.id === "st-mfa"), + sessionRequired: true, + }, userContext ); const bodyParams = await options.req.getJSONBody(); diff --git a/lib/ts/recipe/totp/api/removeDevice.ts b/lib/ts/recipe/totp/api/removeDevice.ts index 65c57fec1..21323c957 100644 --- a/lib/ts/recipe/totp/api/removeDevice.ts +++ b/lib/ts/recipe/totp/api/removeDevice.ts @@ -30,7 +30,11 @@ export default async function removeDeviceAPI( const session = await Session.getSession( options.req, options.res, - { overrideGlobalClaimValidators: () => [], sessionRequired: true }, + { + overrideGlobalClaimValidators: (globalClaimValidators) => + globalClaimValidators.filter((v) => v.id === "st-mfa"), + sessionRequired: true, + }, userContext ); diff --git a/test/test-server/src/testFunctionMapper.ts b/test/test-server/src/testFunctionMapper.ts index 1b48879e2..87f36e9a0 100644 --- a/test/test-server/src/testFunctionMapper.ts +++ b/test/test-server/src/testFunctionMapper.ts @@ -393,6 +393,16 @@ export function getFunc(evalStr: string): (...args: any[]) => any { } if (evalStr.startsWith("multifactorauth.init.override.functions")) { + if (evalStr.includes(`getMFARequirementsForAuth:async()=>["totp"]`)) { + return (e) => { + return { + ...e, + getMFARequirementsForAuth: (e) => { + return ["totp"]; + }, + }; + }; + } return (e) => { return { ...e,