From 2449dc15d8ef34e0102ab441924b276b79b35325 Mon Sep 17 00:00:00 2001 From: grich88 Date: Thu, 16 Oct 2025 00:02:33 +1100 Subject: [PATCH] SECURITY FIX: Add authentication and data filtering to /api/v1/flags endpoint - Require authentication for accessing flags endpoint - Require admin role for sensitive configuration access - Filter sensitive data (AUTH0_DOMAIN, AUTH0_APP_CLIENT_ID, SAML_AUTH_ACS_URL, etc.) - Prevent information disclosure vulnerability Fixes: #309 --- .../backend/api/src/app/flags/flag.module.ts | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/workflow/packages/backend/api/src/app/flags/flag.module.ts b/workflow/packages/backend/api/src/app/flags/flag.module.ts index 83e7ccd5..8391ea77 100644 --- a/workflow/packages/backend/api/src/app/flags/flag.module.ts +++ b/workflow/packages/backend/api/src/app/flags/flag.module.ts @@ -18,16 +18,51 @@ export const flagController: FastifyPluginAsyncTypebox = async (app) => { logLevel: 'silent', }, async (request: FastifyRequest) => { + // Security fix: Require authentication + if (!request.principal) { + return app.httpErrors.unauthorized('Authentication required') + } + + // Security fix: Require admin role for sensitive configuration + if (request.principal.type !== 'ADMIN') { + return app.httpErrors.forbidden('Admin access required') + } + const flags = await flagService.getAll() const flagsMap: Record> = flags.reduce( (map, flag) => ({ ...map, [flag.id as string]: flag.value }), {}, ) + + // Security fix: Filter sensitive configuration data + const safeFlags = filterSensitiveFlags(flagsMap) + return flagHooks.get().modify({ - flags: flagsMap, + flags: safeFlags, request, }) }, ) } + +// Security fix: Filter sensitive configuration data +function filterSensitiveFlags(flags: Record>): Record> { + const sensitiveKeys = [ + 'AUTH0_DOMAIN', + 'AUTH0_APP_CLIENT_ID', + 'SAML_AUTH_ACS_URL', + 'WEBHOOK_URL_PREFIX', + 'THIRD_PARTY_AUTH_PROVIDER_REDIRECT_URL', + 'SUPPORTED_APP_WEBHOOKS' + ] + + const safeFlags = { ...flags } + + // Remove sensitive keys + sensitiveKeys.forEach(key => { + delete safeFlags[key] + }) + + return safeFlags +}