如何用正则表达式从日志输出中移除Authorization请求头?
近期生产日志(prod log drain)中意外记录了Authorization请求头,存在敏感信息泄露风险,示例日志内容如下:
{"response":{"status":"rejected","reason":{"message":"read ECONNRESET","name":"Error","stack":"Error: read ECONNRESET\n at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20)","config":{"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false},"transformRequest":[null],"transformResponse":[null],"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"env":{},"headers":{"Accept":"application/json","Authorization":"Token eyJra...rest...of.token","Content-Type":"application/json","User-Agent":"axios/0.27.2"},"method":"get","url":"https://api.mywebapp.com"},"code":"ECONNRESET","status":null}}}
该日志通过Winston以logger.info(JSON.stringify(errorObj))方式记录,可通过自定义格式化器结合正则表达式移除敏感的Authorization字段。
1. 匹配Authorization字段的正则表达式
使用以下正则全局匹配并替换目标字段:
/"Authorization":\s*"(Token|Bearer)\s+[^"]+"/g
正则说明
"Authorization":\s*:精准匹配字段名及后续任意数量的空格"(Token|Bearer)\s+[^"]+":匹配Token或Bearer开头的令牌内容,直到闭合双引号结束g:开启全局匹配,处理日志中可能出现的多个Authorization字段
2. 配置Winston自定义格式化器
在Winston日志实例中添加格式化器,拦截日志消息并替换敏感内容:
const winston = require('winston'); // 自定义格式化器:清洗Authorization字段 const sanitizeAuthFormatter = winston.format((info) => { if (typeof info.message === 'string') { // 将Authorization字段内容替换为[REDACTED] info.message = info.message.replace(/"Authorization":\s*"(Token|Bearer)\s+[^"]+"/g, '"Authorization": "[REDACTED]"'); } return info; }); // 初始化带有清洗逻辑的logger const logger = winston.createLogger({ format: winston.format.combine( sanitizeAuthFormatter(), winston.format.json() // 保留原有JSON格式化逻辑 ), transports: [ new winston.transports.Console(), // 可添加其他传输方式(如文件、第三方服务) ] });
3. 替换效果验证
处理后的日志会将敏感令牌替换为[REDACTED],示例结果如下:
{"response":{"status":"rejected","reason":{"message":"read ECONNRESET","name":"Error","stack":"Error: read ECONNRESET\n at TLSWrap.onStreamRead (node:internal/stream_base_commons:217:20)","config":{"transitional":{"silentJSONParsing":true,"forcedJSONParsing":true,"clarifyTimeoutError":false},"transformRequest":[null],"transformResponse":[null],"timeout":0,"xsrfCookieName":"XSRF-TOKEN","xsrfHeaderName":"X-XSRF-TOKEN","maxContentLength":-1,"maxBodyLength":-1,"env":{},"headers":{"Accept":"application/json","Authorization":"[REDACTED]","Content-Type":"application/json","User-Agent":"axios/0.27.2"},"method":"get","url":"https://api.mywebapp.com"},"code":"ECONNRESET","status":null}}}
内容的提问来源于stack exchange,提问作者j_d
相关产品推荐
相关产品推荐

