一身转战三千里,一剑曾百万师。这篇文章主要讲述信息安全无小事!手把手教你日志脱敏相关的知识,希望能为你提供帮助。
场景我们开发的程序迟早有一天都会上线到生产环境运行,但是没有人能保证自己的代码100%不出BUG(别抬扛,真没BUG是代码写的少)
当我们线上出BUG之后,最常见的定位问题方法就是排查日志文件,所以我们一般都会在开发程序时,在适当的位置输出一些日志信息。
并且有一些日志并不是只打印一些业务字段,可能会将整个对象输出到日志中。比如这样:
log.info("客户信息:",JSON.toJSONString(customer));
从代码的角度来说,不太严格的话,如果这个?
?customer?
?对象不是特别大的话,倒也没有多大的问题。但是咱们换个角度,从信息安全的角度来说,这会直接将用户的所有信息都打印在日志中。
假设某一天,开发小哥或者运维小哥因为某些不太建议的操作,恶意从日志中获取用户的信息,比如用户的手机号,邮箱,身份证号,家庭住址。。。。如果你们公司是一家金融类公司,直接获取到一些富豪客户的信息,然后去做一些非法交易,后果很严重。
(?????♂?警告:这是反面教材,万万不可尝试)
文章图片
所以我们要怎么避免这种问题的发生呢?
可以从以下几个方面解决:
- 避免在代码中将敏感信息直接输出
- 通过日志组件进行脱敏
- ?
其他我也不知道的方法。。?
接下来的内容主要和大家讲解一下如何通过日志组件进行脱敏。
在java项目中使用的日志组件一般都会选择Logback或者Log4j,前段时间log4j漏洞风波沸沸扬扬,我们pass它,使用logback来做。
LogbackLogback是 Java 社区中使用最广泛的日志记录框架之一。它是其 Log4j 的替代品,比 Log4j 更快,并提供了更多的配置选项,归档日志文件更灵活。
数据脱敏在我们的系统中多多少少都会有敏感信息,比如身份证号,家庭住址,银行卡号,手机号,邮箱等等,我们需要在记录日志时将这些敏感信息进行脱敏。
假设我们会有如下用户信息日志输出:
假设我们会有如下用户信息日志输出:
"user_id":"123456",
"address":"朝阳区百子湾街道某小区1单元101",
"city":"北京市",
"Country":"中国",
"mobile":"18888888888",
"email":"heiz123@xxx.com"
在这个用户信息中,用户的地址,电话,手机,邮箱信息都是比较敏感的,我们需要进行脱敏。
要实现这个功能,我们可以给Logback配置上脱敏规则,将脱敏规则添加到Logback的?
?appender?
?中。我们需要自定义一个Logback的??PatternLayout?
?。自定义PatternLayout我们自定义?
?PatternLayout?
?的目的是为了将脱敏规则添加到logback配置中的所有??appender?
?中。package com.heiz123.log.layout;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
/**
* @author yuriy.lu
* @ClassName MaskingPatternLayout
* @Description
* @date 2022/1/26
**/
public class MaskingPatternLayout extends PatternLayout
private Pattern multilinePattern;
private final List< String> maskPatterns = new ArrayList< > ();
public void addMaskPattern(String maskPattern)
maskPatterns.add(maskPattern);
multilinePattern = Pattern.compile(String.join("|", maskPatterns), Pattern.MULTILINE);
@Override
public String doLayout(ILoggingEvent event)
return maskMessage(super.doLayout(event));
private String maskMessage(String message)
if (multilinePattern == null)
return message;
StringBuilder sb = new StringBuilder(message);
// 使用正则匹配符合脱敏要求的数据
Matcher matcher = multilinePattern.matcher(sb);
while (matcher.find())
IntStream.rangeClosed(1, matcher.groupCount()).forEach(group ->
if (matcher.group(group) != null)
// 将符合格式的数据用*替换
IntStream.range(matcher.start(group), matcher.end(group)).forEach(i -> sb.setCharAt(i, *));
);
return sb.toString();
然后将我们自定义的?
?MaskingPatternLayout?
?配置在??Appender?
?中:< appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
< encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
< layout class="com.heiz123.log.layout.MaskingPatternLayout"> < !-- 自定义layout -->
< maskPattern> \\"address\\"\\s*:\\s*\\"(.*?)\\"< /maskPattern> < !--json地址格式 -->
< maskPattern> ((1\\d2)\\d8)< /maskPattern> < !-- 手机号格式 -->
< maskPattern> (\\w+@\\w+\\.\\w+)< /maskPattern> < !-- 邮箱格式 -->
< Pattern> %dHH:mm:ss.SSS %-5level %logger80 - %msg%n< /Pattern>
< /layout>
< /encoder>
< /appender>
然后我们来测试一下打印结果,使用如下代码模拟用户数据输出:
private static void testLog()
Map< String, String> user = new HashMap< > ();
user.put("user_id", "123456");
user.put("mobile", "18888888888");
user.put("address", "朝阳区百子湾街道某小区1单元101");
user.put("city", "北京市");
user.put("country", "中国");
user.put("email", "heiz123@163.com");
log.info("customer info: ", JSON.toJSONString(user));
执行后输出结果如下:
com.heiz123.study.StudyApplication - customer info: "country":"中国","address":"*****************","user_id":"123456","city":"北京市","mobile":"***********","email":"***************"
嗯,达到了数据脱敏的目的。并且我们可以在配置文件中添加不同的正则表达式,对不同格式的信息进行脱敏。
实现原理俗话说要知其然,知其所以然。
为什么在Appender中添加一个自定义Layout就可以做到脱敏呢?我通过阅读源码,给他家整理了一个Logback日志输出的流程图,方便大家理解。
文章图片
在我们调用?
?log.debug()?
??或者??log.info()?
?以及其他级别的日志方法时,会按照上图中的流程执行。红色字体部分的方法,就会调用到?
?Encoder?
??中的??layout?
??的??doLayout(Event)?
??,也就是我们配置文件中配置的自定义??Layout?
?。文章图片
最后以上就是本期的所有内容,主要跟大家讲解如何通过自定义PatternLayout,对logback输出的敏感日志进行脱敏,防止数据泄露。
如果对你有所帮助,希望能给小黑点个赞,就是对我最大的鼓励啦。
我是小黑,一名在互联网“苟且”的程序员
【信息安全无小事!手把手教你日志脱敏】?流水不争先,贵在滔滔不绝?
推荐阅读
- (服务注册名称的来历)
- win8系统语音识别技巧的运用办法
- 图文 Win8系统修好停止工作弹窗的办法
- 图文 如何让Win8系统打开窗口总是显示菜单栏
- 图文 Win 8系统屏幕亮度无法调节的处理办法
- 图文 Win8系统碎片整理优化图文详细教程
- 图文 Win8系统启用与关闭telnet组件的图文详细教程
- 图文 windows8系统迅速备份图文详细教程
- Win8系统无法打开安全中心服务的处理办法