From a7410020c7a9feba80e38bd200cef2e87ed882ed Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 4 Dec 2023 16:47:41 +0000 Subject: [PATCH 1/2] Adding cookie clearing/logout for when a cross tenant session is detected, make sure that the cookie cannot be used/considered valid after the call is made. --- packages/backend-core/src/tenancy/tenancy.ts | 12 +++++- packages/server/src/middleware/currentapp.ts | 41 ++++++++++++-------- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/packages/backend-core/src/tenancy/tenancy.ts b/packages/backend-core/src/tenancy/tenancy.ts index 7b17bdbe18..3603ef3462 100644 --- a/packages/backend-core/src/tenancy/tenancy.ts +++ b/packages/backend-core/src/tenancy/tenancy.ts @@ -93,11 +93,19 @@ export const getTenantIDFromCtx = ( // subdomain if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) { // e.g. budibase.app or local.com:10000 - const platformHost = new URL(getPlatformURL()).host.split(":")[0] + let platformHost + try { + platformHost = new URL(getPlatformURL()).host.split(":")[0] + } catch (err: any) { + // if invalid URL, just don't try to process subdomain + if (err.code !== "ERR_INVALID_URL") { + throw err + } + } // e.g. tenant.budibase.app or tenant.local.com const requestHost = ctx.host // parse the tenant id from the difference - if (requestHost.includes(platformHost)) { + if (platformHost && requestHost.includes(platformHost)) { const tenantId = requestHost.substring( 0, requestHost.indexOf(`.${platformHost}`) diff --git a/packages/server/src/middleware/currentapp.ts b/packages/server/src/middleware/currentapp.ts index 800d43e69c..8fca5e0c5c 100644 --- a/packages/server/src/middleware/currentapp.ts +++ b/packages/server/src/middleware/currentapp.ts @@ -5,6 +5,7 @@ import { tenancy, context, users, + auth, } from "@budibase/backend-core" import { generateUserMetadataID, isDevAppID } from "../db/utils" import { getCachedSelf } from "../utilities/global" @@ -69,28 +70,34 @@ export default async (ctx: UserCtx, next: any) => { return next() } - return context.doInAppContext(appId, async () => { - // if the user not in the right tenant then make sure they have no permissions - // need to judge this only based on the request app ID, - if ( - env.MULTI_TENANCY && - ctx.user?._id && - requestAppId && - !tenancy.isUserInAppTenant(requestAppId, ctx.user) - ) { - // don't error, simply remove the users rights (they are a public user) - ctx.user = users.cleanseUserObject(ctx.user) as ContextUser - ctx.isAuthenticated = false - roleId = roles.BUILTIN_ROLE_IDS.PUBLIC - } + const userId = ctx.user ? generateUserMetadataID(ctx.user._id!) : undefined + // if the user not in the right tenant then make to wipe their cookie + // also cleanse any information about them that has been allocated + // this avoids apps making calls to say the worker which are cross tenant, + // we simply remove the authentication + if ( + env.MULTI_TENANCY && + userId && + requestAppId && + !tenancy.isUserInAppTenant(requestAppId, ctx.user) + ) { + // clear out the user + ctx.user = users.cleanseUserObject(ctx.user) as ContextUser + ctx.isAuthenticated = false + roleId = roles.BUILTIN_ROLE_IDS.PUBLIC + // remove the cookie, so future calls are public + await auth.platformLogout({ + ctx, + userId, + }) + } + + return context.doInAppContext(appId, async () => { ctx.appId = appId if (roleId) { ctx.roleId = roleId const globalId = ctx.user ? ctx.user._id : undefined - const userId = ctx.user - ? generateUserMetadataID(ctx.user._id!) - : undefined ctx.user = { ...ctx.user!, // override userID with metadata one From c321c839160b6efee3f3aacc3a56ab95d59e9e8b Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Mon, 4 Dec 2023 17:10:19 +0000 Subject: [PATCH 2/2] Update packages/server/src/middleware/currentapp.ts Co-authored-by: Sam Rose --- packages/server/src/middleware/currentapp.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/middleware/currentapp.ts b/packages/server/src/middleware/currentapp.ts index 8fca5e0c5c..984dd8e5e9 100644 --- a/packages/server/src/middleware/currentapp.ts +++ b/packages/server/src/middleware/currentapp.ts @@ -72,7 +72,7 @@ export default async (ctx: UserCtx, next: any) => { const userId = ctx.user ? generateUserMetadataID(ctx.user._id!) : undefined - // if the user not in the right tenant then make to wipe their cookie + // if the user is not in the right tenant then make sure to wipe their cookie // also cleanse any information about them that has been allocated // this avoids apps making calls to say the worker which are cross tenant, // we simply remove the authentication