Skip to content

Commit 8833067

Browse files
Add support to supply a custom mask value
1 parent 6339bc1 commit 8833067

File tree

5 files changed

+122
-7
lines changed

5 files changed

+122
-7
lines changed

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog for Serilog.Enrichers.Sensitive
22

3+
## 1.1.0
4+
5+
- Add support to supply a custom mask value
6+
37
## 1.0.0
48

59
- Removed a number of try/catch blocks that only existed for debugging

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ The effect is that the log message will be rendered as:
9595

9696
See the [Serilog.Enrichers.Sensitive.Demo](src/Serilog.Enrichers.Sensitive.Demo/Program.cs) app for a code example of the above.
9797

98+
## Using a custom mask value
99+
100+
In case the default mask value `***MASKED***` is not what you want, you can supply your own mask value:
101+
102+
```csharp
103+
var logger = new LoggerConfiguration()
104+
.Enrich.WithSensitiveDataMasking(mask: "**")
105+
.WriteTo.Console()
106+
.CreateLogger();
107+
```
108+
109+
A example rendered message would then look like:
110+
111+
`This is a sensitive value: **`
112+
113+
You can specify any mask string as long as it's non-null or an empty string.
114+
98115
## Extending to additional use cases
99116

100117
Extending this enricher is a fairly straight forward process.

src/Serilog.Enrichers.Sensitive/ExtensionMethods.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using Serilog.Configuration;
34

45
namespace Serilog.Enrichers.Sensitive
@@ -19,17 +20,28 @@ public static LoggerConfiguration WithSensitiveDataMasking(this LoggerEnrichment
1920
return loggerConfiguration.WithSensitiveDataMasking(MaskingMode.Globally, SensitiveDataEnricher.DefaultOperators);
2021
}
2122

23+
public static LoggerConfiguration WithSensitiveDataMasking(this LoggerEnrichmentConfiguration loggerConfiguration, string mask)
24+
{
25+
return loggerConfiguration.WithSensitiveDataMasking(MaskingMode.Globally, SensitiveDataEnricher.DefaultOperators, mask);
26+
}
27+
2228
public static LoggerConfiguration WithSensitiveDataMaskingInArea(this LoggerEnrichmentConfiguration loggerConfiguration)
2329
{
2430
return loggerConfiguration.WithSensitiveDataMasking(MaskingMode.InArea, SensitiveDataEnricher.DefaultOperators);
2531
}
2632

33+
public static LoggerConfiguration WithSensitiveDataMaskingInArea(this LoggerEnrichmentConfiguration loggerConfiguration, string mask)
34+
{
35+
return loggerConfiguration.WithSensitiveDataMasking(MaskingMode.InArea, SensitiveDataEnricher.DefaultOperators, mask);
36+
}
37+
2738
public static LoggerConfiguration WithSensitiveDataMasking(
2839
this LoggerEnrichmentConfiguration loggerConfiguration, MaskingMode mode,
29-
IEnumerable<IMaskingOperator> operators)
40+
IEnumerable<IMaskingOperator> operators,
41+
string mask = SensitiveDataEnricher.DefaultMaskValue)
3042
{
3143
return loggerConfiguration
32-
.With(new SensitiveDataEnricher(mode, operators));
44+
.With(new SensitiveDataEnricher(mode, operators, mask));
3345
}
3446
}
3547
}

src/Serilog.Enrichers.Sensitive/SensitiveDataEnricher.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using System.Reflection;
45
using Serilog.Core;
@@ -10,15 +11,23 @@ namespace Serilog.Enrichers.Sensitive
1011
internal class SensitiveDataEnricher : ILogEventEnricher
1112
{
1213
private readonly MaskingMode _maskingMode;
13-
private const string MaskValue = "***MASKED***";
14+
public const string DefaultMaskValue = "***MASKED***";
1415

1516
private static readonly MessageTemplateParser Parser = new MessageTemplateParser();
1617
private readonly FieldInfo _messageTemplateBackingField;
1718
private readonly List<IMaskingOperator> _maskingOperators;
19+
private readonly string _maskValue;
1820

19-
public SensitiveDataEnricher(MaskingMode maskingMode, IEnumerable<IMaskingOperator> maskingOperators)
21+
public SensitiveDataEnricher(MaskingMode maskingMode, IEnumerable<IMaskingOperator> maskingOperators,
22+
string mask = DefaultMaskValue)
2023
{
24+
if (string.IsNullOrEmpty(mask))
25+
{
26+
throw new ArgumentNullException(nameof(mask), "The mask must be a non-empty string");
27+
}
28+
2129
_maskingMode = maskingMode;
30+
_maskValue = mask;
2231

2332
var fields = typeof(LogEvent).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);
2433

@@ -52,7 +61,7 @@ private string ReplaceSensitiveDataFromString(string input)
5261
{
5362
foreach (var maskingOperator in _maskingOperators)
5463
{
55-
var maskResult = maskingOperator.Mask(input, MaskValue);
64+
var maskResult = maskingOperator.Mask(input, _maskValue);
5665

5766
if (maskResult.Match)
5867
{
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System;
2+
using FluentAssertions;
3+
using Serilog.Sinks.InMemory;
4+
using Serilog.Sinks.InMemory.Assertions;
5+
using Xunit;
6+
7+
namespace Serilog.Enrichers.Sensitive.Tests.Unit
8+
{
9+
public class WhenMaskingWithCustomMaskValue
10+
{
11+
[Fact]
12+
public void GivenMaskValueIsNull_ArgumentNullExceptionIsThrown()
13+
{
14+
Action action = () => new LoggerConfiguration()
15+
.Enrich.WithSensitiveDataMasking(null)
16+
.CreateLogger();
17+
18+
action
19+
.Should()
20+
.Throw<ArgumentNullException>();
21+
}
22+
23+
[Fact]
24+
public void GivenMaskValueIsEmptyString_ArgumentNullExceptionIsThrown()
25+
{
26+
Action action = () => new LoggerConfiguration()
27+
.Enrich.WithSensitiveDataMasking(string.Empty)
28+
.CreateLogger();
29+
30+
action
31+
.Should()
32+
.Throw<ArgumentNullException>();
33+
}
34+
35+
[Fact]
36+
public void GivenMaskValue_MaskedLogEntryContainsMaskValue()
37+
{
38+
var inMemorySink = new InMemorySink();
39+
40+
var logger = new LoggerConfiguration()
41+
.Enrich.WithSensitiveDataMasking("SPECIFIC VALUE")
42+
.WriteTo.Sink(inMemorySink)
43+
.CreateLogger();
44+
45+
logger.Information("Example [email protected]");
46+
47+
inMemorySink
48+
.Should()
49+
.HaveMessage("Example SPECIFIC VALUE");
50+
}
51+
52+
[Fact]
53+
public void GivenMaskValueAndLogMessageHasSensitiveDataInProperty_PropertyContainsMaskValue()
54+
{
55+
var inMemorySink = new InMemorySink();
56+
57+
var logger = new LoggerConfiguration()
58+
.Enrich.WithSensitiveDataMasking("SPECIFIC VALUE")
59+
.WriteTo.Sink(inMemorySink)
60+
.CreateLogger();
61+
62+
logger.Information("Example {Email}", "[email protected]");
63+
64+
inMemorySink
65+
.Should()
66+
.HaveMessage("Example {Email}")
67+
.Appearing()
68+
.Once()
69+
.WithProperty("Email")
70+
.WithValue("SPECIFIC VALUE");
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)