log4j-1.x 日志脱敏 扩展PatternLayout类+修改log4j.properties

背景

项目做完,公司安全测试,说系统有安全漏洞,日志中未对用户信息进行脱敏处理,需要我对手机号进行脱敏处理,至少隐藏四位。锅从天上来,一期的项目的安全漏洞,之前没有安全测试,二期项目结束,测出来了,一脸懵的我~
好学和负责任的我(没办法,后来就算不算是二期项目的锅,我是系统Owner,最后还是算是系统问题),开始找资料怎么修复,网上一堆资料,怕个啥。

过程

项目使用的log4j-1.2.16.jar
浏览了很多网页的我,最后有些难受,脱敏的文章,基本上都是基于logback和log4j2的,关于log4j-1.2.16的,找到可用的文章参考总结为以下3种方法:

  1. 直接把要打印之前,把内容替换掉,这个可行,但是是个笨方法,要看每条有手机号的日志有哪些,然后去替换,难受呀,代码不美观,工作量多而且有可能会漏掉;
  2. 把 log4j-1.2.16换成 logback和log4j2,然后再脱敏,工作量同样不小,包名啥的也都不一样,身边的小伙伴建议我不要轻易动这一块,工作量太大,有可能会有大坑;
  3. 重写过滤器,我查了一些文章,没搞懂;
  4. 扩展PatternLayout类,具体怎么扩展,看了一下,不明白;

想扩展PatternLayout类,但又不知如何下手的我,后来就去看了log4j-1.2.16.jar的源码,就只修改log4j.properties和新增了一个ExPatternLayout.class(基本上是org.apache.log4j.PatternLayout类的代码,没改几行代码)

正则表达式只对连续11位数字且开头是1的进行处理,连续数字超过11位的不认为是手机号,不处理

代码

package com.xiaoxi.log;

import org.apache.log4j.PatternLayout;
import org.apache.log4j.helpers.PatternConverter;
import org.apache.log4j.spi.LoggingEvent;

/**
 * 扩展PatternLayout类 
 * 日志手机号码脱敏 第1位数字为1 连续 11位数字 第12位非数字 中间4位用*代替
 */
public class ExPatternLayout extends PatternLayout {
	private static final String REGEX = "1(\\d{2})\\d{4}(\\d{4})(\\D)";
	private static final String REPLACEMENT = "1$1****$2$3";

	private StringBuffer sbuf = new StringBuffer(256);
	private String pattern;
	private PatternConverter head;
	PatternLayout patternLayout;

	public ExPatternLayout() {
		this(DEFAULT_CONVERSION_PATTERN);
	}

	public ExPatternLayout(String pattern) {
		this.pattern = pattern;
		this.head = createPatternParser(pattern).parse();
	}

	@Override
	public void setConversionPattern(String conversionPattern) {
		this.pattern = conversionPattern;
		this.head = createPatternParser(conversionPattern).parse();
	}

	@Override
	public String getConversionPattern() {
		return this.pattern;
	}

	@Override
	public String format(LoggingEvent event) {
		if (this.sbuf.capacity() > 1024)
			this.sbuf = new StringBuffer(256);
		else {
			this.sbuf.setLength(0);
		}
		PatternConverter c = this.head;
		while (c != null) {
			c.format(this.sbuf, event);
			c = c.next;
		}
		// 正则表达式替换之前返回值
		return this.sbuf.toString().replaceAll(REGEX, REPLACEMENT);
	}

}

原先 log4j.properties

log4j.rootLogger = stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p  %c\:%L - %m%n

log4j.properties修改

# 把 log4j.appender.stdout.layout = org.apache.log4j.PatternLayout 修改为
     log4j.appender.stdout.layout = com.xiaoxi.log.ExPatternLayout
log4j.rootLogger = stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout=com.xiaoxi.log.ExPatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %p  %c\:%L - %m%n

测试代码

package com.xiaoxi.log;

import org.apache.log4j.Logger;

public class ExPatternLayoutTest {
	private final static Logger log = Logger.getLogger(PatternLayoutDesensitization.class);
	
	public static void main(String[] args) {
		String phone1="\"phone\":\"15151822400\"";		
		log.info(phone1);
		
		String phone2="\"phone\":\"151518224000\"";		
		log.info(phone2);					
	}
}

结果

2019-03-21 19:42:14.760 [main] INFO  com.xiaoxi.log.ExPatternLayoutTest:10 - "phone":"151****2400"
2019-03-21 19:42:14.763 [main] INFO  com.xiaoxi.log.ExPatternLayoutTest:13 - "phone":"151518224000"

你可能感兴趣的:(Java)