Obfuscate password name value pairs in log strings (#2755)
* Unit test to catch password in logs. * Add clean to logger controller to "look for" password strings in log messages.
This commit is contained in:
@@ -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) => {
|
it("should expose log to trigger", (done) => {
|
||||||
var logController = new LoggerController(new WinstonLoggerAdapter());
|
var logController = new LoggerController(new WinstonLoggerAdapter());
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ export class LoggerController extends AdaptableController {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanAndTruncateLogMessage(string) {
|
||||||
|
return this.truncateLogMessage(this.cleanLogMessage(string));
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanLogMessage(string) {
|
||||||
|
return string.replace(/password":"[^"]*"/g, 'password":"********"');
|
||||||
|
}
|
||||||
|
|
||||||
truncateLogMessage(string) {
|
truncateLogMessage(string) {
|
||||||
if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) {
|
if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) {
|
||||||
const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker;
|
const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker;
|
||||||
|
|||||||
@@ -125,10 +125,10 @@ export class FunctionsRouter extends PromiseRouter {
|
|||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
const userString = (req.auth && req.auth.user) ? req.auth.user.id : undefined;
|
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) => {
|
var response = FunctionsRouter.createResponseObject((result) => {
|
||||||
try {
|
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} `
|
logger.info(`Ran cloud function ${functionName} for user ${userString} `
|
||||||
+ `with:\n Input: ${cleanInput }\n Result: ${cleanResult }`, {
|
+ `with:\n Input: ${cleanInput }\n Result: ${cleanResult }`, {
|
||||||
functionName,
|
functionName,
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ function userIdForLog(auth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logTriggerAfterHook(triggerType, className, input, 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}`, {
|
logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, {
|
||||||
className,
|
className,
|
||||||
triggerType,
|
triggerType,
|
||||||
@@ -221,8 +221,8 @@ function logTriggerAfterHook(triggerType, className, input, auth) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) {
|
function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) {
|
||||||
const cleanInput = logger.truncateLogMessage(JSON.stringify(input));
|
const cleanInput = logger.cleanAndTruncateLogMessage(JSON.stringify(input));
|
||||||
const cleanResult = logger.truncateLogMessage(JSON.stringify(result));
|
const cleanResult = logger.cleanAndTruncateLogMessage(JSON.stringify(result));
|
||||||
logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
|
logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
|
||||||
className,
|
className,
|
||||||
triggerType,
|
triggerType,
|
||||||
@@ -231,7 +231,7 @@ function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth
|
|||||||
}
|
}
|
||||||
|
|
||||||
function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) {
|
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)}`, {
|
logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, {
|
||||||
className,
|
className,
|
||||||
triggerType,
|
triggerType,
|
||||||
|
|||||||
Reference in New Issue
Block a user