Added masking
This commit is contained in:
@@ -5,8 +5,6 @@ VisualStudioVersion = 17.3.32811.315
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EonaCat.Logger", "EonaCat.Logger\EonaCat.Logger.csproj", "{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EonaCat.Logger", "EonaCat.Logger\EonaCat.Logger.csproj", "{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EonaCat.Logger.Test.Console", "Testers\EonaCat.Logger.Test.Console\EonaCat.Logger.Test.Console.csproj", "{8993DE28-C729-417A-99C3-DAF80F32590B}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EonaCat.Logger.Test.Web", "Testers\EonaCat.Logger.Test.Web\EonaCat.Logger.Test.Web.csproj", "{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EonaCat.Logger.Test.Web", "Testers\EonaCat.Logger.Test.Web\EonaCat.Logger.Test.Web.csproj", "{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
@@ -31,18 +29,6 @@ Global
|
|||||||
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x64.Build.0 = Release|Any CPU
|
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x86.ActiveCfg = Release|Any CPU
|
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x86.Build.0 = Release|Any CPU
|
{DCD1D32E-0F24-4D0F-A6B6-59941C0F9BB7}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{8993DE28-C729-417A-99C3-DAF80F32590B}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{DBEEF0B0-68AF-4A98-80B9-17FFCDB96E38}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<TargetFrameworks>.netstandard2.1; net6.0; net7.0; net8.0; net4.8;</TargetFrameworks>
|
<TargetFrameworks>.netstandard2.1; net6.0; net7.0; net8.0; net4.8;</TargetFrameworks>
|
||||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<FileVersion>1.3.0</FileVersion>
|
<FileVersion>1.3.1</FileVersion>
|
||||||
<Authors>EonaCat (Jeroen Saey)</Authors>
|
<Authors>EonaCat (Jeroen Saey)</Authors>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Company>EonaCat (Jeroen Saey)</Company>
|
<Company>EonaCat (Jeroen Saey)</Company>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<EVRevisionFormat>1.3.0+{chash:10}.{c:ymd}</EVRevisionFormat>
|
<EVRevisionFormat>1.3.1+{chash:10}.{c:ymd}</EVRevisionFormat>
|
||||||
<EVDefault>true</EVDefault>
|
<EVDefault>true</EVDefault>
|
||||||
<EVInfo>true</EVInfo>
|
<EVInfo>true</EVInfo>
|
||||||
<EVTagMatch>v[0-9]*</EVTagMatch>
|
<EVTagMatch>v[0-9]*</EVTagMatch>
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EonaCat.Json" Version="1.0.5" />
|
<PackageReference Include="EonaCat.Json" Version="1.0.5" />
|
||||||
<PackageReference Include="EonaCat.Versioning" Version="1.0.5">
|
<PackageReference Include="EonaCat.Versioning" Version="1.0.8">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|||||||
@@ -49,6 +49,10 @@ public static class FileLoggerFactoryExtensions
|
|||||||
options.IsEnabled = fileLoggerOptions.IsEnabled;
|
options.IsEnabled = fileLoggerOptions.IsEnabled;
|
||||||
options.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
|
options.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
|
||||||
options.UseLocalTime = fileLoggerOptions.UseLocalTime;
|
options.UseLocalTime = fileLoggerOptions.UseLocalTime;
|
||||||
|
options.UseMask = fileLoggerOptions.UseMask;
|
||||||
|
options.Mask = fileLoggerOptions.Mask;
|
||||||
|
options.UseDefaultMasking = fileLoggerOptions.UseDefaultMasking;
|
||||||
|
options.MaskedKeywords = fileLoggerOptions.MaskedKeywords;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return builder;
|
return builder;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
using EonaCat.Logger.EonaCatCoreLogger.Internal;
|
||||||
|
|
||||||
@@ -100,4 +101,42 @@ public class FileLoggerOptions : BatchingLoggerOptions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public string LogDirectory { get; set; } = Path.Combine(DefaultPath, "logs");
|
public string LogDirectory { get; set; } = Path.Combine(DefaultPath, "logs");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if we need to mask certain keywords
|
||||||
|
/// </summary>
|
||||||
|
public bool UseMask { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the keywords to mask
|
||||||
|
/// </summary>
|
||||||
|
public List<string> MaskedKeywords { get; set; } = new List<string>();
|
||||||
|
public string Mask { get; set; } = "***MASKED***";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines that if masking is enabled we also need to use the default masking options:
|
||||||
|
/// IP addresses
|
||||||
|
/// MAC addresses
|
||||||
|
/// Emails
|
||||||
|
/// Passwords
|
||||||
|
/// Credit card numbers
|
||||||
|
/// Social security numbers (SSN) and BSN (Dutch Citizen Service Number)
|
||||||
|
/// API keys/tokens
|
||||||
|
/// Phone numbers (generic and Dutch specific)
|
||||||
|
/// Dates of birth (DOB) or other date formats
|
||||||
|
/// IBAN/Bank account numbers (generic and Dutch specific)
|
||||||
|
/// JWT tokens
|
||||||
|
/// URLs with sensitive query strings
|
||||||
|
/// License keys
|
||||||
|
/// Public and private keys (e.g., PEM format)
|
||||||
|
/// Dutch KVK number (8 or 12 digits)
|
||||||
|
/// Dutch BTW-nummer (VAT number)
|
||||||
|
/// Dutch driving license number (10-12 characters)
|
||||||
|
/// Dutch health insurance number (Zorgnummer)
|
||||||
|
/// Other Dutch Bank Account numbers (9-10 digits)
|
||||||
|
/// Dutch Passport Numbers (9 alphanumeric characters
|
||||||
|
/// Dutch Identification Document Numbers (varying formats)
|
||||||
|
/// Custom keywords specified in LoggerSettings
|
||||||
|
/// </summary>
|
||||||
|
public bool UseDefaultMasking { get; set; } = true;
|
||||||
}
|
}
|
||||||
@@ -57,12 +57,10 @@ namespace EonaCat.Logger.EonaCatCoreLogger.Internal
|
|||||||
message = LogHelper.FormatMessageWithHeader(_loggerSettings, logLevel.FromLogLevel(), message, timestamp.DateTime, category)
|
message = LogHelper.FormatMessageWithHeader(_loggerSettings, logLevel.FromLogLevel(), message, timestamp.DateTime, category)
|
||||||
+ Environment.NewLine;
|
+ Environment.NewLine;
|
||||||
|
|
||||||
_provider.AddMessage(timestamp, message);
|
|
||||||
|
|
||||||
var currentMessage = new EonaCatLogMessage
|
var currentMessage = new EonaCatLogMessage
|
||||||
{
|
{
|
||||||
DateTime = timestamp.DateTime,
|
DateTime = timestamp.DateTime,
|
||||||
Message = message,
|
Message = _provider.AddMessage(timestamp, message),
|
||||||
LogType = logLevel.FromLogLevel(),
|
LogType = logLevel.FromLogLevel(),
|
||||||
Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin) ? "BatchingLogger" : _loggerSettings.LogOrigin
|
Origin = string.IsNullOrWhiteSpace(_loggerSettings.LogOrigin) ? "BatchingLogger" : _loggerSettings.LogOrigin
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
if (options.Value is FileLoggerOptions fileLoggerOptions)
|
if (options.Value is FileLoggerOptions fileLoggerOptions)
|
||||||
{
|
{
|
||||||
UseLocalTime = fileLoggerOptions.UseLocalTime;
|
UseLocalTime = fileLoggerOptions.UseLocalTime;
|
||||||
|
UseMask = fileLoggerOptions.UseMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
_batchSize = loggerOptions.BatchSize;
|
_batchSize = loggerOptions.BatchSize;
|
||||||
@@ -61,6 +62,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
|
|
||||||
_loggerSettings = new LoggerSettings();
|
_loggerSettings = new LoggerSettings();
|
||||||
_loggerSettings.UseLocalTime = UseLocalTime;
|
_loggerSettings.UseLocalTime = UseLocalTime;
|
||||||
|
_loggerSettings.UseMask = UseMask;
|
||||||
return _loggerSettings;
|
return _loggerSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool IsStarted { get; set; }
|
public bool IsStarted { get; set; }
|
||||||
|
public bool UseMask { get; set; }
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
@@ -126,18 +129,198 @@ public abstract class BatchingLoggerProvider : ILoggerProvider, IDisposable
|
|||||||
protected async Task WriteStartMessage()
|
protected async Task WriteStartMessage()
|
||||||
{
|
{
|
||||||
var message = LogHelper.GetStartupMessage();
|
var message = LogHelper.GetStartupMessage();
|
||||||
await WriteMessagesAsync(new List<LogMessage> { new LogMessage() { Message = message, Timestamp = CurrentDateTimeOffset } }, _cancellationTokenSource.Token).ConfigureAwait(false);
|
await WriteMessagesAsync(new List<LogMessage> { CreateLoggerMessage(message, CurrentDateTimeOffset) }, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LogMessage CreateLoggerMessage(string message, DateTimeOffset currentDateTimeOffset)
|
||||||
|
{
|
||||||
|
var result = new LogMessage() { Message = message, Timestamp = currentDateTimeOffset };
|
||||||
|
|
||||||
|
if (LoggerSettings != null && LoggerSettings.UseMask)
|
||||||
|
{
|
||||||
|
// Masking sensitive information
|
||||||
|
result.Message = MaskSensitiveInformation(result.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Masks sensitive information within the provided message string.
|
||||||
|
/// This method is virtual and can be overridden to customize masking behavior.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The log message potentially containing sensitive information.</param>
|
||||||
|
/// <returns>The masked log message.</returns>
|
||||||
|
protected virtual string MaskSensitiveInformation(string message)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(message))
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LoggerSettings != null && LoggerSettings.UseDefaultMasking)
|
||||||
|
{
|
||||||
|
// Mask IP addresses
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(?:\d{1,3}\.){3}\d{1,3}\b(?!\d)",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask MAC addresses
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(?:[0-9A-Fa-f]{2}[:-]){5}[0-9A-Fa-f]{2}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask emails
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b",
|
||||||
|
LoggerSettings.Mask,
|
||||||
|
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
// Mask passwords
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"(?i)(password\s*[:= ]\s*|pwd\s*[:= ]\s*)[^\s]+",
|
||||||
|
$"password={LoggerSettings.Mask}");
|
||||||
|
|
||||||
|
// Mask credit card numbers
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(?:\d{4}[ -]?){3}\d{4}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask social security numbers (SSN) and BSN (Dutch Citizen Service Number)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{3}-\d{2}-\d{4}\b|\b\d{9}\b",
|
||||||
|
LoggerSettings.Mask); // SSN (USA)
|
||||||
|
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{9}\b",
|
||||||
|
LoggerSettings.Mask); // BSN (Dutch)
|
||||||
|
|
||||||
|
// Mask passwords (Dutch)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"(?i)(wachtwoord\s*[:= ]\s*|ww\s*=\s*)[^\s]+",
|
||||||
|
$"wachtwoord={LoggerSettings.Mask}");
|
||||||
|
|
||||||
|
// Mask API keys/tokens
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Za-z0-9-_]{20,}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask phone numbers (generic and Dutch specific)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(\+?\d{1,4}[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}\b",
|
||||||
|
LoggerSettings.Mask); // Generic
|
||||||
|
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(\+31|0031|0|06)[-\s]?\d{8}\b",
|
||||||
|
LoggerSettings.Mask); // Dutch
|
||||||
|
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b(\+32|0032|0|06)[-\s]?\d{8}\b",
|
||||||
|
LoggerSettings.Mask); // Belgium
|
||||||
|
|
||||||
|
// Mask dates of birth (DOB) or other date formats
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{2}[/-]\d{2}[/-]\d{4}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch postal codes
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{4}\s?[A-Z]{2}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask IBAN/Bank account numbers (generic and Dutch specific)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z]{2}\d{2}[A-Z0-9]{1,30}\b",
|
||||||
|
LoggerSettings.Mask); // Generic for EU and other country IBANs
|
||||||
|
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\bNL\d{2}[A-Z]{4}\d{10}\b",
|
||||||
|
LoggerSettings.Mask); // Dutch IBAN
|
||||||
|
|
||||||
|
// Mask JWT Tokens
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Za-z0-9-_]{16,}\.[A-Za-z0-9-_]{16,}\.[A-Za-z0-9-_]{16,}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask URLs with sensitive query strings
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\bhttps?:\/\/[^\s?]+(\?[^\s]+?[\&=](password|key|token|wachtwoord|sleutel))[^&\s]*",
|
||||||
|
LoggerSettings.Mask,
|
||||||
|
System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
|
// Mask license keys
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask public and private keys (e.g., PEM format)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"-----BEGIN [A-Z ]+KEY-----[\s\S]+?-----END [A-Z ]+KEY-----",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch KVK number (8 or 12 digits)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{8}|\d{12}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch BTW-nummer (VAT number)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\bNL\d{9}B\d{2}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch driving license number (10-12 characters)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z0-9]{10,12}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch health insurance number (Zorgnummer)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{9}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask other Dutch Bank Account numbers (9-10 digits)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b\d{9,10}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch Passport Numbers (9 alphanumeric characters)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z0-9]{9}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
|
||||||
|
// Mask Dutch Identification Document Numbers (varying formats)
|
||||||
|
message = System.Text.RegularExpressions.Regex.Replace(message,
|
||||||
|
@"\b[A-Z]{2}\d{6,7}\b",
|
||||||
|
LoggerSettings.Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mask custom keywords specified in LoggerSettings
|
||||||
|
if (LoggerSettings?.MaskedKeywords != null)
|
||||||
|
{
|
||||||
|
foreach (var keyword in LoggerSettings.MaskedKeywords)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(keyword))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
message = message.Replace(keyword, LoggerSettings.Mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task WriteStopMessage()
|
private async Task WriteStopMessage()
|
||||||
{
|
{
|
||||||
var message = LogHelper.GetStopMessage();
|
var message = LogHelper.GetStopMessage();
|
||||||
await WriteMessagesAsync(new List<LogMessage> { new LogMessage() { Message = message, Timestamp = CurrentDateTimeOffset } }, _cancellationTokenSource.Token).ConfigureAwait(false);
|
await WriteMessagesAsync(new List<LogMessage> { CreateLoggerMessage(message, CurrentDateTimeOffset) }, _cancellationTokenSource.Token).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddMessage(DateTimeOffset timestamp, string message)
|
internal string AddMessage(DateTimeOffset timestamp, string message)
|
||||||
{
|
{
|
||||||
_messageQueue.Enqueue(new LogMessage { Message = message, Timestamp = timestamp });
|
var result = CreateLoggerMessage(message, timestamp);
|
||||||
|
_messageQueue.Enqueue(result);
|
||||||
|
return result.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task StartAsync()
|
private Task StartAsync()
|
||||||
|
|||||||
@@ -175,6 +175,10 @@ namespace EonaCat.Logger.Managers
|
|||||||
configuration.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
|
configuration.FileNamePrefix = fileLoggerOptions.FileNamePrefix;
|
||||||
configuration.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
|
configuration.MaxRolloverFiles = fileLoggerOptions.MaxRolloverFiles;
|
||||||
configuration.UseLocalTime = Settings.UseLocalTime;
|
configuration.UseLocalTime = Settings.UseLocalTime;
|
||||||
|
configuration.UseMask = Settings.UseMask;
|
||||||
|
configuration.Mask = fileLoggerOptions.Mask;
|
||||||
|
configuration.UseDefaultMasking = Settings.UseDefaultMasking;
|
||||||
|
configuration.MaskedKeywords = fileLoggerOptions.MaskedKeywords;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var serviceProvider = serviceCollection.BuildServiceProvider();
|
var serviceProvider = serviceCollection.BuildServiceProvider();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger;
|
using EonaCat.Logger.EonaCatCoreLogger;
|
||||||
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
using EonaCat.Logger.EonaCatCoreLogger.Models;
|
||||||
using EonaCat.Logger.GrayLog;
|
using EonaCat.Logger.GrayLog;
|
||||||
@@ -167,6 +168,44 @@ public class LoggerSettings
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string LogOrigin { get; set; }
|
public string LogOrigin { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines if we need to mask certain keywords
|
||||||
|
/// </summary>
|
||||||
|
public bool UseMask { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines the keywords to mask
|
||||||
|
/// </summary>
|
||||||
|
public List<string> MaskedKeywords { get; set; } = new List<string>();
|
||||||
|
public string Mask { get; set; } = "***MASKED***";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines that if masking is enabled we also need to use the default masking options:
|
||||||
|
/// IP addresses
|
||||||
|
/// MAC addresses
|
||||||
|
/// Emails
|
||||||
|
/// Passwords
|
||||||
|
/// Credit card numbers
|
||||||
|
/// Social security numbers (SSN) and BSN (Dutch Citizen Service Number)
|
||||||
|
/// API keys/tokens
|
||||||
|
/// Phone numbers (generic and Dutch specific)
|
||||||
|
/// Dates of birth (DOB) or other date formats
|
||||||
|
/// IBAN/Bank account numbers (generic and Dutch specific)
|
||||||
|
/// JWT tokens
|
||||||
|
/// URLs with sensitive query strings
|
||||||
|
/// License keys
|
||||||
|
/// Public and private keys (e.g., PEM format)
|
||||||
|
/// Dutch KVK number (8 or 12 digits)
|
||||||
|
/// Dutch BTW-nummer (VAT number)
|
||||||
|
/// Dutch driving license number (10-12 characters)
|
||||||
|
/// Dutch health insurance number (Zorgnummer)
|
||||||
|
/// Other Dutch Bank Account numbers (9-10 digits)
|
||||||
|
/// Dutch Passport Numbers (9 alphanumeric characters
|
||||||
|
/// Dutch Identification Document Numbers (varying formats)
|
||||||
|
/// Custom keywords specified in LoggerSettings
|
||||||
|
/// </summary>
|
||||||
|
public bool UseDefaultMasking { get; set; } = true;
|
||||||
|
|
||||||
public event LogDelegate OnLog;
|
public event LogDelegate OnLog;
|
||||||
|
|
||||||
private static FileLoggerOptions CreateDefaultFileLoggerOptions()
|
private static FileLoggerOptions CreateDefaultFileLoggerOptions()
|
||||||
|
|||||||
37
README.md
37
README.md
@@ -267,6 +267,43 @@ namespace EonaCat.Logger.Advanced
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Code for enabling keyword masking (default: false):**
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
Logger.LoggerSettings.UseMask = true;
|
||||||
|
```
|
||||||
|
|
||||||
|
Sensitive information will be replaced with ****MASKED****
|
||||||
|
You can add additional masking keywords using the MaskedKeywords property on the LoggerSettings object
|
||||||
|
|
||||||
|
You can also override the MaskSensitiveInformation method of the batchLoggingProvider to add your own masking
|
||||||
|
|
||||||
|
|
||||||
|
Default maskings (when the masking is enabled):
|
||||||
|
IP addresses
|
||||||
|
MAC addresses
|
||||||
|
Emails
|
||||||
|
Passwords
|
||||||
|
Credit card numbers
|
||||||
|
Social security numbers (SSN) and BSN (Dutch Citizen Service Number)
|
||||||
|
API keys/tokens
|
||||||
|
Phone numbers (generic and Dutch specific)
|
||||||
|
Dates of birth (DOB) or other date formats
|
||||||
|
IBAN/Bank account numbers (generic and Dutch specific)
|
||||||
|
JWT tokens
|
||||||
|
URLs with sensitive query strings
|
||||||
|
License keys
|
||||||
|
Public and private keys (e.g., PEM format)
|
||||||
|
Dutch KVK number (8 or 12 digits)
|
||||||
|
Dutch BTW-nummer (VAT number)
|
||||||
|
Dutch driving license number (10-12 characters)
|
||||||
|
Dutch health insurance number (Zorgnummer)
|
||||||
|
Other Dutch Bank Account numbers (9-10 digits)
|
||||||
|
Dutch Passport Numbers (9 alphanumeric characters
|
||||||
|
Dutch Identification Document Numbers (varying formats)
|
||||||
|
Custom keywords specified in LoggerSettings
|
||||||
|
|
||||||
|
|
||||||
**Code for enabling GrayLog in the above *advanced* logger class:**
|
**Code for enabling GrayLog in the above *advanced* logger class:**
|
||||||
|
|
||||||
```csharp
|
```csharp
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EonaCat.Web.RateLimiter" Version="1.0.2" />
|
<PackageReference Include="EonaCat.Web.RateLimiter" Version="1.0.3" />
|
||||||
<PackageReference Include="EonaCat.Web.Tracer" Version="1.0.1" />
|
<PackageReference Include="EonaCat.Web.Tracer" Version="1.1.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using EonaCat.Logger.Test.Web;
|
|||||||
using EonaCat.Web.RateLimiter;
|
using EonaCat.Web.RateLimiter;
|
||||||
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
using EonaCat.Web.RateLimiter.Endpoints.Extensions;
|
||||||
using EonaCat.Web.Tracer.Extensions;
|
using EonaCat.Web.Tracer.Extensions;
|
||||||
|
using EonaCat.Web.Tracer.Models;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
int onLogCounter = 0;
|
int onLogCounter = 0;
|
||||||
@@ -17,6 +18,7 @@ Logger logger = new Logger();
|
|||||||
logger.UseLocalTime = true;
|
logger.UseLocalTime = true;
|
||||||
logger.MaxLogType = ELogType.TRACE;
|
logger.MaxLogType = ELogType.TRACE;
|
||||||
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
logger.LoggerSettings.OnLog += LoggerSettings_OnLog;
|
||||||
|
logger.LoggerSettings.UseMask = true;
|
||||||
|
|
||||||
void LoggerSettings_OnLog(EonaCatLogMessage message)
|
void LoggerSettings_OnLog(EonaCatLogMessage message)
|
||||||
{
|
{
|
||||||
@@ -29,6 +31,7 @@ var options = new FileLoggerOptions();
|
|||||||
options.MaxRolloverFiles = 5;
|
options.MaxRolloverFiles = 5;
|
||||||
//options.FileSizeLimit = 1 * 1024 * 1024 / 4;
|
//options.FileSizeLimit = 1 * 1024 * 1024 / 4;
|
||||||
options.UseLocalTime = true;
|
options.UseLocalTime = true;
|
||||||
|
options.UseMask = true;
|
||||||
builder.Logging.AddEonaCatFileLogger(fileLoggerOptions: options, filenamePrefix: "web");
|
builder.Logging.AddEonaCatFileLogger(fileLoggerOptions: options, filenamePrefix: "web");
|
||||||
|
|
||||||
builder.Services.AddRazorPages();
|
builder.Services.AddRazorPages();
|
||||||
@@ -94,12 +97,7 @@ if (!app.Environment.IsDevelopment())
|
|||||||
//{
|
//{
|
||||||
// await httpContext.Response.WriteAsync("THIS IS MY CUSTOM RATE LIMIT MESSAGE");
|
// await httpContext.Response.WriteAsync("THIS IS MY CUSTOM RATE LIMIT MESSAGE");
|
||||||
//}
|
//}
|
||||||
WebTracer.OnLog += WebTracer_OnLog;
|
|
||||||
|
|
||||||
void WebTracer_OnLog(object? sender, string e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
}
|
|
||||||
//app.UseWebTracer();
|
//app.UseWebTracer();
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
@@ -135,6 +133,7 @@ void RunLoggingExceptionTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await Task.Run(RunMaskTest).ConfigureAwait(false);
|
||||||
await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
|
await Task.Run(RunWebLoggerTestsAsync).ConfigureAwait(false);
|
||||||
await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
await Task.Run(RunWebLoggingTests).ConfigureAwait(false);
|
||||||
await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
|
await Task.Run(RunLoggingTestsAsync).ConfigureAwait(false);
|
||||||
@@ -183,6 +182,29 @@ async void RunWebLoggingTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async void RunMaskTest()
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(logger.LogFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(logger.LogFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < 9000000; i++)
|
||||||
|
{
|
||||||
|
var message = $"mask-test {i}";
|
||||||
|
app.Logger.LogInformation("password: test");
|
||||||
|
app.Logger.LogInformation("JWT Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
|
||||||
|
app.Logger.LogInformation("JWT Token2: eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.iOeNU4dAFFeBwNj6qdhdvm-IvDQrTa6R22lQVJVuWJxorJfeQww5Nwsra0PjaOYhAMj9jNMO5YLmud8U7iQ5gJK2zYyepeSuXhfSi8yjFZfRiSkelqSkU19I-Ja8aQBDbqXf2SAWA8mHF8VS3F08rgEaLCyv98fLLH4vSvsJGf6ueZSLKDVXz24rZRXGWtYYk_OYYTVgR1cg0BLCsuCvqZvHleImJKiWmtS0-CymMO4MMjCy_FIl6I56NqLE9C87tUVpo1mT-kbg5cHDD8I7MjCW5Iii5dethB4Vid3mZ6emKjVYgXrtkOQ-JyGMh6fnQxEFN1ft33GX2eRHluK9eg");
|
||||||
|
|
||||||
|
using (var file = new StreamWriter(Path.Combine(logger.LogFolder, "testmask.log"), true))
|
||||||
|
{
|
||||||
|
file.WriteAsync(message);
|
||||||
|
}
|
||||||
|
Console.WriteLine($"Masked: {i}");
|
||||||
|
Task.Delay(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async Task RunLoggingTestsAsync()
|
async Task RunLoggingTestsAsync()
|
||||||
{
|
{
|
||||||
var loggerSettings = new LoggerSettings();
|
var loggerSettings = new LoggerSettings();
|
||||||
|
|||||||
Reference in New Issue
Block a user