diff --git a/spec/CloudCodeLogger.spec.js b/spec/CloudCodeLogger.spec.js index a10b894b..a2be5655 100644 --- a/spec/CloudCodeLogger.spec.js +++ b/spec/CloudCodeLogger.spec.js @@ -55,6 +55,24 @@ describe("Cloud Code Logger", () => { }); }); + it('trigger should obfuscate password', done => { + const logController = new LoggerController(new WinstonLoggerAdapter()); + + Parse.Cloud.beforeSave(Parse.User, (req, res) => { + res.success(req.object); + }); + + Parse.User.signUp('tester123', 'abc') + .then(() => logController.getLogs({ from: Date.now() - 500, size: 1000 })) + .then((res) => { + const entry = res[0]; + expect(entry.message).not.toMatch(/password":"abc/); + expect(entry.message).toMatch(/\*\*\*\*\*\*\*\*/); + done(); + }) + .then(null, e => done.fail(e)); + }); + it("should expose log to trigger", (done) => { var logController = new LoggerController(new WinstonLoggerAdapter()); diff --git a/src/Controllers/LoggerController.js b/src/Controllers/LoggerController.js index 59a6ab94..8904daa1 100644 --- a/src/Controllers/LoggerController.js +++ b/src/Controllers/LoggerController.js @@ -61,6 +61,14 @@ export class LoggerController extends AdaptableController { return null; } + cleanAndTruncateLogMessage(string) { + return this.truncateLogMessage(this.cleanLogMessage(string)); + } + + cleanLogMessage(string) { + return string.replace(/password":"[^"]*"/g, 'password":"********"'); + } + truncateLogMessage(string) { if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) { const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker; diff --git a/src/Routers/FunctionsRouter.js b/src/Routers/FunctionsRouter.js index 9a3b12ab..306d8882 100644 --- a/src/Routers/FunctionsRouter.js +++ b/src/Routers/FunctionsRouter.js @@ -103,7 +103,7 @@ export class FunctionsRouter extends PromiseRouter { const applicationId = req.config.applicationId; const theFunction = triggers.getFunction(functionName, applicationId); const theValidator = triggers.getValidator(req.params.functionName, applicationId); - if (theFunction) { + if (theFunction) { let params = Object.assign({}, req.body, req.query); params = parseParams(params); var request = { @@ -125,10 +125,10 @@ export class FunctionsRouter extends PromiseRouter { return new Promise(function (resolve, reject) { const userString = (req.auth && req.auth.user) ? req.auth.user.id : undefined; - const cleanInput = logger.truncateLogMessage(JSON.stringify(params)); + const cleanInput = logger.cleanAndTruncateLogMessage(JSON.stringify(params)); var response = FunctionsRouter.createResponseObject((result) => { try { - const cleanResult = logger.truncateLogMessage(JSON.stringify(result.response.result)); + const cleanResult = logger.cleanAndTruncateLogMessage(JSON.stringify(result.response.result)); logger.info(`Ran cloud function ${functionName} for user ${userString} ` + `with:\n Input: ${cleanInput }\n Result: ${cleanResult }`, { functionName, diff --git a/src/triggers.js b/src/triggers.js index 0bbce382..1a1119af 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -212,7 +212,7 @@ function userIdForLog(auth) { } function logTriggerAfterHook(triggerType, className, input, auth) { - const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); + const cleanInput = logger.cleanAndTruncateLogMessage(JSON.stringify(input)); logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, { className, triggerType, @@ -221,8 +221,8 @@ function logTriggerAfterHook(triggerType, className, input, auth) { } function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { - const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); - const cleanResult = logger.truncateLogMessage(JSON.stringify(result)); + const cleanInput = logger.cleanAndTruncateLogMessage(JSON.stringify(input)); + const cleanResult = logger.cleanAndTruncateLogMessage(JSON.stringify(result)); logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { className, triggerType, @@ -231,7 +231,7 @@ function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth } function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { - const cleanInput = logger.truncateLogMessage(JSON.stringify(input)); + const cleanInput = logger.cleanAndTruncateLogMessage(JSON.stringify(input)); logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, { className, triggerType,