You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js的Bunyan日志中排除敏感数据(密码、CVV、PIN等)

Hey there! Great question—keeping sensitive data like passwords, CVV codes, or PINs out of your logs is critical for security and compliance. Let’s break down the best ways to handle this with Bunyan in Node.js:

Bunyan relies on serializers to format objects like req, res, or err into log-friendly JSON. You can override the default serializers to redact sensitive fields before they hit the logs.

First, define a list of sensitive fields you want to hide, then create a custom serializer that sanitizes those fields:

const bunyan = require('bunyan');

// List all sensitive fields you need to redact
const sensitiveFields = ['password', 'cvv', 'pin', 'creditCardNumber'];

// Custom serializers with sanitization
const customSerializers = {
  req: (req) => {
    if (!req) return req;
    
    // Create a copy of the request object to avoid modifying the original
    const sanitizedReq = { ...req };
    
    // Sanitize request body
    if (sanitizedReq.body) {
      sensitiveFields.forEach(field => {
        if (sanitizedReq.body[field]) {
          sanitizedReq.body[field] = '[REDACTED]';
        }
      });
    }
    
    // Sanitize query parameters (if needed)
    if (sanitizedReq.query) {
      sensitiveFields.forEach(field => {
        if (sanitizedReq.query[field]) {
          sanitizedReq.query[field] = '[REDACTED]';
        }
      });
    }
    
    // Fall back to Bunyan's default req serializer for other fields
    return bunyan.stdSerializers.req(sanitizedReq);
  },
  // Keep the default error serializer unless you need to redact sensitive data there too
  err: bunyan.stdSerializers.err
};

// Initialize your logger with the custom serializers
const logger = bunyan.createLogger({
  name: 'my-secure-app',
  serializers: customSerializers,
  level: 'info'
});

// Test it out!
logger.info({
  req: {
    method: 'POST',
    url: '/api/payment',
    body: {
      userId: '12345',
      creditCardNumber: '4111-1111-1111-1111',
      cvv: '123',
      amount: 99.99
    }
  }
}, 'Payment request received');
2. Global Sanitization with a Transform Function

If you want to redact sensitive fields across all log entries (not just specific objects like req), you can use a transform function on your Bunyan stream. This lets you modify the log record right before it’s written:

const bunyan = require('bunyan');

const sensitiveFields = ['password', 'cvv', 'pin'];

// Recursive function to sanitize nested objects
function sanitizeData(data) {
  if (typeof data !== 'object' || data === null) return data;
  
  const sanitized = { ...data };
  
  // Redact top-level sensitive fields
  sensitiveFields.forEach(field => {
    if (sanitized[field]) {
      sanitized[field] = '[REDACTED]';
    }
  });
  
  // Recursively sanitize nested objects
  Object.keys(sanitized).forEach(key => {
    sanitized[key] = sanitizeData(sanitized[key]);
  });
  
  return sanitized;
}

const logger = bunyan.createLogger({
  name: 'my-app',
  streams: [{
    level: 'info',
    stream: process.stdout,
    // Transform the log record before output
    transform: (record) => {
      // Sanitize any data attached to the record
      if (record.data) {
        record.data = sanitizeData(record.data);
      }
      // You can also sanitize other parts of the record if needed
      return record;
    }
  }]
});

// Test nested data
logger.info({
  data: {
    user: {
      name: 'Jane Doe',
      password: 'mysecretpassword',
      paymentDetails: {
        pin: '4567',
        balance: 500
      }
    }
  }
}, 'User profile updated');
3. Framework-Specific Middleware (e.g., Express)

If you’re using a web framework like Express, you can add middleware to sanitize request data before it gets logged. This ensures you never accidentally log sensitive fields in route handlers:

const express = require('express');
const bunyan = require('bunyan');

const app = express();
app.use(express.json());

const sensitiveFields = ['password', 'cvv', 'pin'];
const logger = bunyan.createLogger({ name: 'express-app' });

// Middleware to sanitize request body
app.use((req, res, next) => {
  // Create a sanitized copy of the body
  req.sanitizedBody = { ...req.body };
  sensitiveFields.forEach(field => {
    if (req.sanitizedBody[field]) {
      req.sanitizedBody[field] = '[REDACTED]';
    }
  });
  next();
});

// Example route
app.post('/login', (req, res) => {
  // Use req.sanitizedBody in logs, not the original req.body
  logger.info({ body: req.sanitizedBody }, 'Login attempt');
  
  // Your authentication logic here (use original req.body for validation)
  res.send('Login processed');
});

app.listen(3000);
Key Tips to Remember
  • Never modify the original request/response object: Always work with copies to avoid breaking your application logic.
  • Recursively sanitize nested objects: Sensitive data might be hidden in deep structures (like user.paymentDetails.pin).
  • Keep your sensitive fields list updated: Add new fields as your application evolves (e.g., socialSecurityNumber).
  • Test thoroughly: Check your logs to confirm no sensitive data is leaking through.

内容的提问来源于stack exchange,提问作者Sabbir Sayed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:41:24