使用 Serilog 防止日志中的敏感数据暴露
介绍
文章都是来自于外国大佬的文章,我这边进行一个翻译,并加上一些自己的理解和解释。
源作者链接:https://sangau.me/prevent-sensitive-data-exposure-in-log-with-serilog
1.问题
在开发应用程序时编写日志,有助于开发者轻松调试和跟踪。但是写好日志是不够的,因为日志中可能会暴露一些敏感数据,例如:密码、帐号或类似的东西。
2.想法
为了防止这个问题,我们需要将所有敏感词替换为任何掩码字符。本文的目的是帮助您使用 Serilog(.NET Core 中常见的记录器扩展之一)实现简单的敏感数据破坏策略。通过应用此策略,您可以防止日志中的敏感数据泄露。够了,让我们看一下代码……
3. 实施
3.1。技术栈
.NET Core(在本文中,我使用 .NET 6.0)
Serilog
3.2 显示代码
要实现破坏策略,我们需要从命名空间Serilog.Core实现接口IDestructuringPolicy
public class SensitiveDataDestructuringPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
throw new NotImplementedException();
}
}
现在,我们需要定义一个掩码值(例如 * 字符)和敏感关键字列表
var mask = "******";
var sensitiveKeywords = new List<string> {
"Password", "NewPassword",
};
实际上,我们应该在配置文件等一些地方定义敏感关键字列表。
我们将查找所有日志事件属性,如果在日志对象中发现任何敏感关键字,我们将使用掩码值创建一个新的日志事件属性,并将新的此属性添加到新的 日志事件属性列表中,用于非敏感关键字,我们还创建了一个新的Log Event Property,但保持原来的值。之后,只需返回结果。
贝娄是完整的代码。
using Microsoft.Extensions.Configuration;
using Serilog.Core;
using Serilog.Events;
using System.Reflection;
namespace Microsoft.Extensions.Logging;
public class SensitiveDataDestructuringPolicy : IDestructuringPolicy
{
private const string DEFAULT_MASK_VALUE = "******";
private const string SENSITIVE_KEYWORDS_SECTION = "Logging:SensitiveData:Keywords";
private const string MASK_VALUE = "Logging:SensitiveData:Mask";
private readonly IConfiguration _configuration;
public SensitiveDataDestructuringPolicy(IConfiguration configuration)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
}
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
{
var sensitiveKeywords = _configuration.GetValue<string[]>(SENSITIVE_KEYWORDS_SECTION) ?? Array.Empty<string>();
var maskValue = _configuration.GetValue<string>(MASK_VALUE) ?? DEFAULT_MASK_VALUE;
if (!sensitiveKeywords.Any())
{
result = new StructureValue(new LogEventProperty[] { });
return false;
}
var props = value.GetType().GetTypeInfo().DeclaredProperties;
var logEventProperties = new List<LogEventProperty>();
foreach (var propertyInfo in props)
{
if (sensitiveKeywords.Any(x => x.Equals(propertyInfo.Name, StringComparison.InvariantCultureIgnoreCase)))
{
logEventProperties.Add(new LogEventProperty(propertyInfo.Name, propertyValueFactory.CreatePropertyValue(maskValue)));
}
else
{
logEventProperties.Add(new LogEventProperty(propertyInfo.Name, propertyValueFactory.CreatePropertyValue(propertyInfo.GetValue(value))));
}
}
result = new StructureValue(logEventProperties);
return true;
}
}
最后,将SensitiveDataDestructuringPolicy添加到loggerConfiguration中,如下所示:
# Rest of code
.UseSerilog((context, services, configuration) =>
{
var loggerConfiguration = configuration
.ReadFrom.Configuration(context.Configuration)
.Enrich.FromLogContext()
.Enrich.WithProperty("Application", context.HostingEnvironment.ApplicationName)
.Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName)
.MinimumLevel.Information();
loggerConfiguration.Destructure.With<SensitiveDataDestructuringPolicy>();
});
4. 结束语
通过应用SensitiveDataDestructuringPolicy,您将使日志更安全,这有助于防止敏感数据在跟踪日志时暴露。
备注:上面的示例只是一个非常简单的示例,您可以修改、优化以适合您的项目。