From 876ace386a4cbfef26f1a6c4303624cfda21077a Mon Sep 17 00:00:00 2001 From: Derek Arner Date: Thu, 7 Aug 2025 11:52:37 -0600 Subject: [PATCH] fix(api-gateway): remove stack information from error responses when not in dev mode to prevent leaking internals in prod --- packages/cubejs-api-gateway/src/gateway.ts | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/cubejs-api-gateway/src/gateway.ts b/packages/cubejs-api-gateway/src/gateway.ts index dd9f0985bde99..b128f21fb7e8e 100644 --- a/packages/cubejs-api-gateway/src/gateway.ts +++ b/packages/cubejs-api-gateway/src/gateway.ts @@ -260,8 +260,9 @@ class ApiGateway { const jsonQuery = getJsonQueryFromGraphQLQuery(query, metaConfig, variables); res.json({ jsonQuery }); } catch (e: any) { + const stack = getEnv('devMode') ? e.stack : undefined; this.logger('GraphQL to JSON error', { - error: (e.stack || e).toString(), + error: (stack || e).toString(), }); res.json({ jsonQuery: null }); } @@ -2180,6 +2181,7 @@ class ApiGateway { e, context, query, res, requestStarted }: HandleErrorOptions) { const requestId = getEnv('devMode') || context?.signedWithPlaygroundAuthSecret ? context?.requestId : undefined; + const stack = getEnv('devMode') ? e.stack : undefined; const plainError = e.plainMessages; @@ -2190,7 +2192,7 @@ class ApiGateway { error: e.message, duration: this.duration(requestStarted) }, context); - res({ error: e.message, stack: e.stack, requestId, plainError }, { status: e.status }); + res({ error: e.message, stack, requestId, plainError }, { status: e.status }); } else if (e.error === 'Continue wait') { this.log({ type: 'Continue wait', @@ -2219,7 +2221,7 @@ class ApiGateway { type: e.type, error: e.message, plainError, - stack: e.stack, + stack, requestId }, { status: 400 } @@ -2228,10 +2230,10 @@ class ApiGateway { this.log({ type: 'Internal Server Error', query, - error: e.stack || e.toString(), + error: stack || e.toString(), duration: this.duration(requestStarted) }, context); - res({ error: e.toString(), stack: e.stack, requestId, plainError, }, { status: 500 }); + res({ error: e.toString(), stack, requestId, plainError, }, { status: 500 }); } } @@ -2497,24 +2499,26 @@ class ApiGateway { } catch (e: unknown) { if (e instanceof CubejsHandlerError) { const error = e.originalError || e; + const stack = getEnv('devMode') ? error.stack : undefined; this.log({ type: error.message, url: req.url, token, - error: error.stack || error.toString() + error: stack || error.toString() }, req); res.status(e.status).json({ error: e.message }); } else if (e instanceof Error) { + const stack = getEnv('devMode') ? e.stack : undefined; this.log({ type: 'Auth Error', token, - error: e.stack || e.toString() + error: stack || e.toString() }, req); res.status(500).json({ error: e.toString(), - stack: e.stack + stack, }); } } @@ -2644,10 +2648,11 @@ class ApiGateway { }; private logProbeError(e: any, type: string): void { + const stack = getEnv('devMode') ? (e as Error).stack : undefined; this.log({ type, driverType: e.driverType, - error: (e as Error).stack || (e as Error).toString(), + error: stack || (e as Error).toString(), }); }