156 lines
3.7 KiB
JavaScript
156 lines
3.7 KiB
JavaScript
/**
|
|
* Data Sanitization Utility
|
|
* CWE-532: Prevents logging of sensitive data
|
|
* Ensures compliance with HIPAA, PCI, SOX regulations
|
|
*/
|
|
|
|
const SENSITIVE_FIELDS = [
|
|
'password',
|
|
'newPassword',
|
|
'oldPassword',
|
|
'currentPassword',
|
|
'confirmPassword',
|
|
'token',
|
|
'accessToken',
|
|
'refreshToken',
|
|
'jwt',
|
|
'secret',
|
|
'apiKey',
|
|
'api_key',
|
|
'privateKey',
|
|
'private_key',
|
|
'two_factor_secret',
|
|
'twoFactorSecret',
|
|
'backup_codes',
|
|
'backupCodes',
|
|
'creditCard',
|
|
'credit_card',
|
|
'cvv',
|
|
'ssn',
|
|
'social_security',
|
|
'pin',
|
|
'authCode',
|
|
'auth_code'
|
|
];
|
|
|
|
/**
|
|
* Sanitize object by removing or masking sensitive fields
|
|
* @param {Object} data - Object to sanitize
|
|
* @param {Array} additionalFields - Additional fields to sanitize
|
|
* @returns {Object} Sanitized object
|
|
*/
|
|
function sanitizeForLogging(data, additionalFields = []) {
|
|
if (!data || typeof data !== 'object') {
|
|
return data;
|
|
}
|
|
|
|
const sensitiveFields = [...SENSITIVE_FIELDS, ...additionalFields];
|
|
const sanitized = Array.isArray(data) ? [] : {};
|
|
|
|
for (const [key, value] of Object.entries(data)) {
|
|
const lowerKey = key.toLowerCase();
|
|
const isSensitive = sensitiveFields.some(field =>
|
|
lowerKey.includes(field.toLowerCase())
|
|
);
|
|
|
|
if (isSensitive) {
|
|
sanitized[key] = '[REDACTED]';
|
|
} else if (value && typeof value === 'object') {
|
|
sanitized[key] = sanitizeForLogging(value, additionalFields);
|
|
} else {
|
|
sanitized[key] = value;
|
|
}
|
|
}
|
|
|
|
return sanitized;
|
|
}
|
|
|
|
/**
|
|
* Sanitize user object for export (remove password hash)
|
|
* @param {Object} user - User object from database
|
|
* @returns {Object} Sanitized user object
|
|
*/
|
|
function sanitizeUserForExport(user) {
|
|
if (!user) return user;
|
|
|
|
const sanitized = { ...user };
|
|
delete sanitized.password;
|
|
delete sanitized.two_factor_secret;
|
|
delete sanitized.backup_codes;
|
|
|
|
return sanitized;
|
|
}
|
|
|
|
/**
|
|
* Sanitize user array for export
|
|
* @param {Array} users - Array of user objects
|
|
* @returns {Array} Sanitized user array
|
|
*/
|
|
function sanitizeUsersForExport(users) {
|
|
if (!Array.isArray(users)) return users;
|
|
return users.map(user => sanitizeUserForExport(user));
|
|
}
|
|
|
|
/**
|
|
* Mask token for logging (show only last 8 characters)
|
|
* @param {String} token - Token to mask
|
|
* @returns {String} Masked token
|
|
*/
|
|
function maskToken(token) {
|
|
if (!token || typeof token !== 'string') return '[INVALID_TOKEN]';
|
|
if (token.length <= 8) return '***';
|
|
return '...' + token.slice(-8);
|
|
}
|
|
|
|
/**
|
|
* Mask email for logging (show only domain)
|
|
* @param {String} email - Email to mask
|
|
* @returns {String} Masked email
|
|
*/
|
|
function maskEmail(email) {
|
|
if (!email || typeof email !== 'string') return '[INVALID_EMAIL]';
|
|
const parts = email.split('@');
|
|
if (parts.length !== 2) return '[INVALID_EMAIL]';
|
|
return `***@${parts[1]}`;
|
|
}
|
|
|
|
/**
|
|
* Sanitize request body for logging
|
|
* @param {Object} body - Request body
|
|
* @returns {Object} Sanitized body
|
|
*/
|
|
function sanitizeRequestBody(body) {
|
|
return sanitizeForLogging(body);
|
|
}
|
|
|
|
/**
|
|
* Create safe metadata object for audit logging
|
|
* Ensures no sensitive data is included in audit logs
|
|
* @param {Object} data - Data to include in audit metadata
|
|
* @returns {Object} Safe metadata object
|
|
*/
|
|
function createSafeAuditMetadata(data) {
|
|
const safe = sanitizeForLogging(data);
|
|
|
|
// Specifically handle common patterns
|
|
if (safe.user && typeof safe.user === 'object') {
|
|
safe.user = sanitizeUserForExport(safe.user);
|
|
}
|
|
|
|
if (safe.changes && typeof safe.changes === 'object') {
|
|
safe.changes = sanitizeForLogging(safe.changes);
|
|
}
|
|
|
|
return safe;
|
|
}
|
|
|
|
module.exports = {
|
|
sanitizeForLogging,
|
|
sanitizeUserForExport,
|
|
sanitizeUsersForExport,
|
|
maskToken,
|
|
maskEmail,
|
|
sanitizeRequestBody,
|
|
createSafeAuditMetadata,
|
|
SENSITIVE_FIELDS
|
|
};
|