Фильтр для logger на c#
Вопрос заключается в том, что в рамках устранения Log Forgin типа XSS уязвимости необходимо все сообщения типа string, которые падают в _logger.Information(string message) предварительно до отправки прогонять через функцию очистки. Каким образом это можно организовать в общем для всех используемых логгеров в приложении на уровне общей логики ибо оборачивать message в каждом логгере - это будет страх и ужас. Само сообщение компанутеся из строк и взодных параметров эндпоинтов. То есть вопрос, как строку, положенную в логгер, до логгирования прогнать через другой метод?
Ответы (1 шт):
Для решения вашей задачи достаточно реализовать собственный форматтер логирования.
Console log formatting
Я взял пример из документации и лишь слегка изменил.
public sealed class CustomFormatter : ConsoleFormatter, IDisposable
{
private readonly IDisposable _optionsReloadToken;
private CustomOptions _formatterOptions;
public CustomFormatter(IOptionsMonitor<CustomOptions> options)
// Case insensitive
: base("customName") =>
(_optionsReloadToken, _formatterOptions) =
(options.OnChange(ReloadLoggerOptions), options.CurrentValue);
private void ReloadLoggerOptions(CustomOptions options) =>
_formatterOptions = options;
public override void Write<TState>(
in LogEntry<TState> logEntry,
IExternalScopeProvider scopeProvider,
TextWriter textWriter)
{
string? message =
logEntry.Formatter?.Invoke(logEntry.State, logEntry.Exception);
if (message is null)
{
return;
}
message = Filter(message, _formatterOptions);
textWriter.WriteLine(message);
}
private string Filter(string message, CustomOptions _formatterOptions)
{
return message.Replace(_formatterOptions.OldValue, _formatterOptions.NewValue);
}
public void Dispose() => _optionsReloadToken?.Dispose();
}
Очистка происходит в методе Filter. Реализуйте там свою логику.
Так выглядит класс с настройками:
public class CustomOptions : ConsoleFormatterOptions
{
public string? OldValue { get; set; }
public string? NewValue { get; set; }
}
Метод расширения
public static class ConsoleLoggerExtensions
{
public static ILoggingBuilder AddCustomFormatter(
this ILoggingBuilder builder,
Action<CustomOptions> configure) =>
builder
.AddConsole(options => options.FormatterName = "customName")
.AddConsoleFormatter<CustomFormatter, CustomOptions>(configure);
}
Регистрируем наш форматтер. Код может различаться в зависимости хоста.
builder.Services.AddLogging(builder =>
builder.AddCustomFormatter(options =>
{
options.OldValue = "#";
options.NewValue = "";
}));
В итоге сообщение #Hello# превращается в Hello.
При желании можно создать собственные провайдер и логгер.
Implement a custom logging provider in .NET
Это даст больше возможностей, но сложнее в реализации.