Repository: FlowiseAI/Flowise
File: packages/server/src/utils/logger.ts (TypeScript)

Code before:
export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
    const unwantedLogURLs = ['/api/v1/node-icon/', '/api/v1/components-credentials-icon/', '/api/v1/ping']

    if (/\/api\/v1\//i.test(req.url) && !unwantedLogURLs.some((url) => new RegExp(url, 'i').test(req.url))) {
        const sanitizedBody = sanitizeObject(req.body)

        const sanitizedQuery = sanitizeObject(req.query)
        const sanitizedHeaders = { ...req.headers }

        const sensitiveHeaders = getSensitiveHeaderFields()
        sensitiveHeaders.forEach((header) => {
            if (sanitizedHeaders[header]) {
                sanitizedHeaders[header] = '********'
            }
        })

        const requestMetadata = {
            request: {
                method: req.method,
                url: req.url,
                body: sanitizedBody,
                query: sanitizedQuery,
                params: req.params,
                headers: sanitizedHeaders
            }
        }

        const getRequestEmoji = (method: string) => {
            const requetsEmojis: Record<string, string> = {
                GET: '⬇️',
                POST: '⬆️',
                PUT: '🖊',
                DELETE: '❌',
                OPTION: '🔗'
            }

            return requetsEmojis[method] || '?'
        }

        if (req.method !== 'GET') {
            requestLogger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`, requestMetadata)
            logger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
        } else {
            requestLogger.http(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`, requestMetadata)
        }
    }

    next()
}

export default logger

Review comment (bug):
Even with redaction, logging HTTP request bodies, params and query strings is generally a bad idea because it significantly increases the risk of accidental exposure of sensitive data due to misconfigurations, broken redaction logic, or logs being improperly secured. It also creates a massive compliance burden under regulations like GDPR and CCPA, as these logs can inadvertently capture Personally Identifiable Information that must then be managed and defensibly deleted.

Recommend either removing body, params & querystring from here or putting them behind a log level so they're only captured when debug logs are enabled.

Code after:
export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
    const unwantedLogURLs = ['/api/v1/node-icon/', '/api/v1/components-credentials-icon/', '/api/v1/ping']

    if (/\/api\/v1\//i.test(req.url) && !unwantedLogURLs.some((url) => new RegExp(url, 'i').test(req.url))) {
        const isDebugLevel = logger.level === 'debug' || process.env.DEBUG === 'true'

        const requestMetadata: any = {
            request: {
                method: req.method,
                url: req.url,
                params: req.params
            }
        }

        // Only include headers, body, and query if log level is debug
        if (isDebugLevel) {
            const sanitizedBody = sanitizeObject(req.body)
            const sanitizedQuery = sanitizeObject(req.query)
            const sanitizedHeaders = { ...req.headers }

            const sensitiveHeaders = getSensitiveHeaderFields()
            sensitiveHeaders.forEach((header) => {
                if (sanitizedHeaders[header]) {
                    sanitizedHeaders[header] = '********'
                }
            })

            requestMetadata.request.body = sanitizedBody
            requestMetadata.request.query = sanitizedQuery
            requestMetadata.request.headers = sanitizedHeaders
        }

        const getRequestEmoji = (method: string) => {
            const requetsEmojis: Record<string, string> = {
                GET: '⬇️',
                POST: '⬆️',
                PUT: '🖊',
                DELETE: '❌',
                OPTION: '🔗'
            }

            return requetsEmojis[method] || '?'
        }

        if (req.method !== 'GET') {
            requestLogger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`, requestMetadata)
            logger.info(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`)
        } else {
            requestLogger.http(`${getRequestEmoji(req.method)} ${req.method} ${req.url}`, requestMetadata)
        }
    }