diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000000..39e142eb2e --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2025-03-19 - Sensitive Data Leakage in Error Parameters +**Vulnerability:** JWT tokens and License Keys were being included in the `params` of `ActivepiecesError`. +**Learning:** The global backend error handler in `packages/server/api/src/app/helper/error-handler.ts` serializes all `error.error.params` directly to the client. If sensitive data like tokens or keys are included in these params, they are leaked in API responses. +**Prevention:** Always use `Record` or ensure no sensitive fields are included in error parameter types defined in `packages/shared/src/lib/common/activepieces-error.ts`. diff --git a/packages/server/api/src/app/app.ts b/packages/server/api/src/app/app.ts index 671220419f..fb687fc050 100644 --- a/packages/server/api/src/app/app.ts +++ b/packages/server/api/src/app/app.ts @@ -83,6 +83,7 @@ import { pieceSyncService } from './pieces/piece-sync-service' import { platformModule } from './platform/platform.module' import { platformService } from './platform/platform.service' import { projectHooks } from './project/project-hooks' +import { platformUtils } from './platform/platform.utils' import { projectModule } from './project/project-module' import { storeEntryModule } from './store-entry/store-entry.module' import { tablesModule } from './tables/tables.module' @@ -250,12 +251,14 @@ export const setupApp = async (app: FastifyInstance): Promise = return reply.send('The code is missing in url') } else { + const platformId = await platformUtils.getPlatformIdForRequest(request) + const targetOrigin = new URL(await domainHelper.getPublicUrl({ platformId })).origin return reply .type('text/html') .send( ` Redirect succuesfully, this window should close now`, + )}' }, '${targetOrigin}')} Redirect successfully, this window should close now`, ) } }, diff --git a/packages/server/api/src/app/ee/connection-keys/connection-key.service.ts b/packages/server/api/src/app/ee/connection-keys/connection-key.service.ts index 86efae473a..ad94b1287d 100644 --- a/packages/server/api/src/app/ee/connection-keys/connection-key.service.ts +++ b/packages/server/api/src/app/ee/connection-keys/connection-key.service.ts @@ -46,9 +46,7 @@ export const connectionKeyService = (log: FastifyBaseLogger) => ({ if (connectionName == null) { throw new ActivepiecesError({ code: ErrorCode.INVALID_OR_EXPIRED_JWT_TOKEN, - params: { - token, - }, + params: {}, }) } const connection = await appConnectionService(log).getOne({ @@ -74,9 +72,7 @@ export const connectionKeyService = (log: FastifyBaseLogger) => ({ if (connectionName == null) { throw new ActivepiecesError({ code: ErrorCode.INVALID_OR_EXPIRED_JWT_TOKEN, - params: { - token: request.token, - }, + params: {}, }) } diff --git a/packages/server/api/src/app/ee/license-keys/license-keys-controller.ts b/packages/server/api/src/app/ee/license-keys/license-keys-controller.ts index 753ebcb95b..5930ff6bda 100644 --- a/packages/server/api/src/app/ee/license-keys/license-keys-controller.ts +++ b/packages/server/api/src/app/ee/license-keys/license-keys-controller.ts @@ -40,9 +40,7 @@ export const licenseKeysController: FastifyPluginAsyncTypebox = async (app) => { if (isNil(key)) { throw new ActivepiecesError({ code: ErrorCode.INVALID_LICENSE_KEY, - params: { - key: licenseKey, - }, + params: {}, }) } await platformService.update({ diff --git a/packages/shared/src/lib/common/activepieces-error.ts b/packages/shared/src/lib/common/activepieces-error.ts index 0805b4144c..7911c85f79 100755 --- a/packages/shared/src/lib/common/activepieces-error.ts +++ b/packages/shared/src/lib/common/activepieces-error.ts @@ -278,9 +278,7 @@ ErrorCode.FLOW_IN_USE, export type InvalidJwtTokenErrorParams = BaseErrorParams< ErrorCode.INVALID_OR_EXPIRED_JWT_TOKEN, -{ - token: string -} +Record > export type TestTriggerFailedErrorParams = BaseErrorParams< @@ -405,9 +403,7 @@ ErrorCode.EXISTING_ALERT_CHANNEL, export type InvalidOtpParams = BaseErrorParams> -export type InvalidLicenseKeyParams = BaseErrorParams +export type InvalidLicenseKeyParams = BaseErrorParams> export type EmailAlreadyHasActivationKey = BaseErrorParams