← 中文资源

简体中文版本

Pino 敏感日志字段脱敏

通过 Pino 的 redact 路径配置在日志序列化前擦除授权头、令牌与密码字段,支持嵌套通配与自定义审查函数。

阅读英文原文

示例说明

日志泄漏密钥是高频安全事故:一次带授权头的错误日志就足以把生产凭证送进日志平台。Pino 的 redact 在序列化阶段生效,被命中的路径会被替换,性能开销极小。路径语法支持点分嵌套、方括号键名与星号通配,能覆盖常见凭证字段位置。

技术要点

  • 点分路径精确命中嵌套字段
  • 星号通配匹配任意层级的 token 字段
  • censor 函数可保留长度信息辅助排障

代码解读

paths 同时列出请求头授权信息、API key、密码与通配形式的 token 字段;censor 用函数生成带原始长度的占位值,安全的同时保留长度特征用于格式排障。第二行日志演示 password 与任意嵌套深度下的 token 都会被拦截替换,其余字段正常输出。

使用建议

脱敏名单应纳入安全评审流程,新增字段同步维护。censor 输出不要包含任何原值片段。更彻底的做法是在源头就避免把凭证放进日志对象,redact 是最后防线。

代码示例

import { pino } from 'pino';

const logger = pino({
  redact: {
    paths: [
      'req.headers.authorization',
      'req.headers["x-api-key"]',
      'password',
      '*.token',
      'user.credentials.*',
    ],
    censor: (value) => (typeof value === 'string' ? '[redacted:' + value.length + ']' : '[redacted]'),
  },
});

const req = {
  id: 'req-91',
  headers: { authorization: 'Bearer eyJhbGciOi', 'x-api-key': 'sk-live-9f2' },
};

logger.info({ req, user: { token: 'abc123', name: 'ada' } }, 'authenticated request');
logger.info({ password: 'hunter2', nested: { token: 'zzz' } }, 'form submitted');