Sanitize sensitive fields in request header and body in logger (#5279)

* Sanitize sensitive fields in request header and body in logger

* fix: log request headers, body, and query only when debug logs are enabled
This commit is contained in:
Ilango 2025-10-27 13:06:34 +05:30 committed by GitHub
parent 6f94d61f22
commit 2ae4678da4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 56 additions and 11 deletions

View File

@ -38,6 +38,8 @@ PORT=3000
# DEBUG=true # DEBUG=true
# LOG_PATH=/your_log_path/.flowise/logs # LOG_PATH=/your_log_path/.flowise/logs
# LOG_LEVEL=info #(error | warn | info | verbose | debug) # LOG_LEVEL=info #(error | warn | info | verbose | debug)
# LOG_SANITIZE_BODY_FIELDS=password,pwd,pass,secret,token,apikey,api_key,accesstoken,access_token,refreshtoken,refresh_token,clientsecret,client_secret,privatekey,private_key,secretkey,secret_key,auth,authorization,credential,credentials
# LOG_SANITIZE_HEADER_FIELDS=authorization,x-api-key,x-auth-token,cookie
# TOOL_FUNCTION_BUILTIN_DEP=crypto,fs # TOOL_FUNCTION_BUILTIN_DEP=crypto,fs
# TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash # TOOL_FUNCTION_EXTERNAL_DEP=moment,lodash
# ALLOW_BUILTIN_DEP=false # ALLOW_BUILTIN_DEP=false

View File

@ -193,28 +193,71 @@ requestLogger = createLogger({
] ]
}) })
function getSensitiveBodyFields(): string[] {
return (process.env.LOG_SANITIZE_BODY_FIELDS as string)
.toLowerCase()
.split(',')
.map((f) => f.trim())
}
function getSensitiveHeaderFields(): string[] {
return (process.env.LOG_SANITIZE_HEADER_FIELDS as string)
.toLowerCase()
.split(',')
.map((f) => f.trim())
}
function sanitizeObject(obj: any): any {
if (!obj || typeof obj !== 'object') return obj
const sensitiveFields = getSensitiveBodyFields()
const sanitized = Array.isArray(obj) ? [...obj] : { ...obj }
Object.keys(sanitized).forEach((key) => {
const lowerKey = key.toLowerCase()
if (sensitiveFields.includes(lowerKey)) {
sanitized[key] = '********'
} else if (typeof sanitized[key] === 'string') {
if (sanitized[key].includes('@') && sanitized[key].includes('.')) {
sanitized[key] = sanitized[key].replace(/([^@\s]+)@([^@\s]+)/g, '**********')
}
}
})
return sanitized
}
export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void { export function expressRequestLogger(req: Request, res: Response, next: NextFunction): void {
const unwantedLogURLs = ['/api/v1/node-icon/', '/api/v1/components-credentials-icon/', '/api/v1/ping'] 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))) { if (/\/api\/v1\//i.test(req.url) && !unwantedLogURLs.some((url) => new RegExp(url, 'i').test(req.url))) {
// Create a sanitized copy of the request body const isDebugLevel = logger.level === 'debug' || process.env.DEBUG === 'true'
const sanitizedBody = { ...req.body }
if (sanitizedBody.password) {
sanitizedBody.password = '********'
}
// Use the shared requestLogger with request-specific metadata const requestMetadata: any = {
const requestMetadata = {
request: { request: {
method: req.method, method: req.method,
url: req.url, url: req.url,
body: sanitizedBody, // Use sanitized body instead of raw body params: req.params
query: req.query,
params: req.params,
headers: req.headers
} }
} }
// 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 getRequestEmoji = (method: string) => {
const requetsEmojis: Record<string, string> = { const requetsEmojis: Record<string, string> = {
GET: '⬇️', GET: '⬇️',