使用 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,您将使日志更安全,这有助于防止敏感数据在跟踪日志时暴露。

备注:上面的示例只是一个非常简单的示例,您可以修改、优化以适合您的项目。

posted @ 2022-08-01 10:18  初久的私房菜  阅读(427)  评论(0编辑  收藏  举报
作者:初久的私房菜
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
张弛:https://blog.zhangchi.fun/