From 2868fd6bf644caa2c07441c5033d6e5f5b3b8d9c Mon Sep 17 00:00:00 2001 From: Rijk van Zanten Date: Thu, 17 Jun 2021 10:57:52 -0400 Subject: [PATCH] Redact tokens from logs (#6347) --- api/package.json | 2 +- api/src/app.ts | 5 ++--- api/src/logger.ts | 32 +++++++++++++++++++++++++++++++- api/src/types/shims.d.ts | 10 ++++++++++ package-lock.json | 20 ++------------------ 5 files changed, 46 insertions(+), 23 deletions(-) diff --git a/api/package.json b/api/package.json index b8f48edbf1656..847f832a3566b 100644 --- a/api/package.json +++ b/api/package.json @@ -95,7 +95,6 @@ "execa": "^5.1.1", "exif-reader": "^1.0.3", "express": "^4.17.1", - "express-pino-logger": "^6.0.0", "express-session": "^1.17.2", "fs-extra": "^10.0.0", "grant": "^5.4.14", @@ -125,6 +124,7 @@ "otplib": "^12.0.1", "pino": "^6.11.3", "pino-colada": "^2.1.0", + "pino-http": "^5.5.0", "prettier": "^2.3.1", "qs": "^6.9.4", "rate-limiter-flexible": "^2.2.2", diff --git a/api/src/app.ts b/api/src/app.ts index d6a21961c8c88..58c4273a72374 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -1,6 +1,5 @@ import cookieParser from 'cookie-parser'; import express, { RequestHandler } from 'express'; -import expressLogger from 'express-pino-logger'; import fse from 'fs-extra'; import path from 'path'; import qs from 'qs'; @@ -30,7 +29,7 @@ import { emitAsyncSafe } from './emitter'; import env from './env'; import { InvalidPayloadException } from './exceptions'; import { initializeExtensions, registerExtensionEndpoints, registerExtensionHooks } from './extensions'; -import logger from './logger'; +import logger, { expressLogger } from './logger'; import authenticate from './middleware/authenticate'; import cache from './middleware/cache'; import { checkIP } from './middleware/check-ip'; @@ -71,7 +70,7 @@ export default async function createApp(): Promise { await emitAsyncSafe('middlewares.init.before', { app }); - app.use(expressLogger({ logger }) as RequestHandler); + app.use(expressLogger); app.use((req, res, next) => { ( diff --git a/api/src/logger.ts b/api/src/logger.ts index 7fc3a887b5ef3..d03bd7aa2d9b0 100644 --- a/api/src/logger.ts +++ b/api/src/logger.ts @@ -1,7 +1,16 @@ +import { Request, RequestHandler } from 'express'; import pino, { LoggerOptions } from 'pino'; +import pinoHTTP, { stdSerializers } from 'pino-http'; +import { URL } from 'url'; import env from './env'; -const pinoOptions: LoggerOptions = { level: env.LOG_LEVEL || 'info' }; +const pinoOptions: LoggerOptions = { + level: env.LOG_LEVEL || 'info', + redact: { + paths: ['req.headers.authorization', 'req.cookies.directus_refresh_token'], + censor: '--redact--', + }, +}; if (env.LOG_STYLE !== 'raw') { pinoOptions.prettyPrint = true; @@ -10,4 +19,25 @@ if (env.LOG_STYLE !== 'raw') { const logger = pino(pinoOptions); +export const expressLogger = pinoHTTP({ + logger, + serializers: { + req(request: Request) { + const output = stdSerializers.req(request); + output.url = redactQuery(output.url); + return output; + }, + }, +}) as RequestHandler; + export default logger; + +function redactQuery(originalPath: string) { + const url = new URL(originalPath, 'http://example.com/'); + + if (url.searchParams.has('access_token')) { + url.searchParams.set('access_token', '--redacted--'); + } + + return url.pathname + url.search; +} diff --git a/api/src/types/shims.d.ts b/api/src/types/shims.d.ts index e6b2ea5b54aad..0ac4ebbd70b40 100644 --- a/api/src/types/shims.d.ts +++ b/api/src/types/shims.d.ts @@ -1,3 +1,5 @@ +import PinoHttp from '@types/pino-http'; + declare module 'grant' { const grant: any; export default grant; @@ -12,3 +14,11 @@ declare module 'exif-reader' { const exifReader: (buf: Buffer) => Record; export default exifReader; } + +declare module 'pino-http' { + const pinoHttp: PinoHttp; + export default pinoHttp; + export const stdSerializers: { + req: (req: any) => Record; + }; +} diff --git a/package-lock.json b/package-lock.json index d9ee8025c8478..79899255d8f64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,6 @@ "execa": "^5.1.1", "exif-reader": "^1.0.3", "express": "^4.17.1", - "express-pino-logger": "^6.0.0", "express-session": "^1.17.2", "fs-extra": "^10.0.0", "grant": "^5.4.14", @@ -116,6 +115,7 @@ "otplib": "^12.0.1", "pino": "^6.11.3", "pino-colada": "^2.1.0", + "pino-http": "^5.5.0", "prettier": "^2.3.1", "qs": "^6.9.4", "rate-limiter-flexible": "^2.2.2", @@ -19386,14 +19386,6 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "peer": true }, - "node_modules/express-pino-logger": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/express-pino-logger/-/express-pino-logger-6.0.0.tgz", - "integrity": "sha512-YjBnalqgsNylRnWEpQGf8YzBP54stpoqX/o+SnpGr04OB7dRIQlsC1qvutFOyRjhLhXIWCe43pYJcjp9zM1Ccg==", - "dependencies": { - "pino-http": "^5.3.0" - } - }, "node_modules/express-session": { "version": "1.17.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", @@ -72863,7 +72855,6 @@ "execa": "^5.1.1", "exif-reader": "^1.0.3", "express": "^4.17.1", - "express-pino-logger": "^6.0.0", "express-session": "^1.17.2", "fs-extra": "^10.0.0", "grant": "^5.4.14", @@ -72900,6 +72891,7 @@ "pg": "^8.6.0", "pino": "^6.11.3", "pino-colada": "^2.1.0", + "pino-http": "*", "prettier": "^2.3.1", "qs": "^6.9.4", "rate-limiter-flexible": "^2.2.2", @@ -74953,14 +74945,6 @@ } } }, - "express-pino-logger": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/express-pino-logger/-/express-pino-logger-6.0.0.tgz", - "integrity": "sha512-YjBnalqgsNylRnWEpQGf8YzBP54stpoqX/o+SnpGr04OB7dRIQlsC1qvutFOyRjhLhXIWCe43pYJcjp9zM1Ccg==", - "requires": { - "pino-http": "^5.3.0" - } - }, "express-session": { "version": "1.17.2", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz",