Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes regression with sensitive data filter #25

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private static void AddBodyLogger(IServiceCollection services)
services.AddScoped<IBodyReader, BodyReader>();
services.AddScoped<ITelemetryWriter, TelemetryWriter>();
services.AddSingleton<ITelemetryInitializer, ClientIpInitializer>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddScoped<ISensitiveDataFilter, SensitiveDataFilter>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Options;

namespace Azureblue.ApplicationInsights.RequestLogging
{
Expand All @@ -14,16 +15,10 @@
private readonly HashSet<string> _sensitiveDataPropertyKeys;
private readonly IEnumerable<string> _regexesForSensitiveValues;


public SensitiveDataFilter(BodyLoggerOptions options) : this(options.PropertyNamesWithSensitiveData, options.SensitiveDataRegexes)
{

}

public SensitiveDataFilter(IEnumerable<string> sensitiveDataPropertyKeys, IEnumerable<string> regexesForSensitiveValues)
public SensitiveDataFilter(IOptions<BodyLoggerOptions> options)
{
_sensitiveDataPropertyKeys = sensitiveDataPropertyKeys.Select(t => t.ToLowerInvariant()).ToHashSet();
_regexesForSensitiveValues = regexesForSensitiveValues;
_sensitiveDataPropertyKeys = options.Value.PropertyNamesWithSensitiveData.Select(t => t.ToLowerInvariant()).ToHashSet();
_regexesForSensitiveValues = options.Value.SensitiveDataRegexes;
}

public string RemoveSensitiveData(string textOrJson)
Expand All @@ -33,7 +28,8 @@
var json = JsonNode.Parse(textOrJson);
if (json == null) return string.Empty;

if (json is JsonValue jValue && TestIfContainsSensitiveData("", jValue.ToString(), _sensitiveDataPropertyKeys, _regexesForSensitiveValues))
if (json is JsonValue jValue &&
TestIfContainsSensitiveData("", jValue.ToString(), _sensitiveDataPropertyKeys, _regexesForSensitiveValues))
{
return SensitiveValueMask;
}
Expand Down Expand Up @@ -90,7 +86,7 @@

foreach (var jNode in jArray.Where(v => v != null))
{
RemoveIds(jNode);

Check warning on line 89 in src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'node' in 'void SensitiveDataFilter.RemoveIds(JsonNode node)'.

Check warning on line 89 in src/ApplicationInsightsRequestLogging/Filters/SensitiveDataFilter.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'node' in 'void SensitiveDataFilter.RemoveIds(JsonNode node)'.
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Moq;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using Microsoft.Extensions.Options;

namespace ApplicationInsightsRequestLoggingTests
{
Expand Down Expand Up @@ -43,13 +44,13 @@ public async void BodyLoggerMiddleware_should_not_log_request_body_if_downstream
.UseTestServer()
.ConfigureServices(services =>
{
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddSingleton(telemetryWriter.Object);
services.AddOptions<BodyLoggerOptions>().Configure(options =>
{
options.EnableBodyLoggingOnExceptions = false;
});
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddSingleton(telemetryWriter.Object);
services.AddTransient<BodyLoggerMiddleware>();
})
.Configure(app =>
Expand Down Expand Up @@ -87,13 +88,13 @@ public async void BodyLoggerMiddleware_should_log_request_body_if_downstream_exc
.UseTestServer()
.ConfigureServices(services =>
{
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddSingleton(telemetryWriter.Object);
services.AddOptions<BodyLoggerOptions>().Configure(options =>
{
options.EnableBodyLoggingOnExceptions = true;
});
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddSingleton(telemetryWriter.Object);
services.AddTransient<BodyLoggerMiddleware>();
})
.Configure(app =>
Expand Down Expand Up @@ -254,11 +255,13 @@ public async void BodyLoggerMiddleware_should_redact_password()
.UseTestServer()
.ConfigureServices(services =>
{
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter>(provider =>
services.AddOptions<BodyLoggerOptions>().Configure(options =>
{
return new SensitiveDataFilter(new List<string>() { "password" }, new List<string>());
options.PropertyNamesWithSensitiveData = new List<string> { "password" };
options.SensitiveDataRegexes = new List<string>();
});
services.AddTransient<IBodyReader, BodyReader>();
services.AddTransient<ISensitiveDataFilter, SensitiveDataFilter>();
services.AddSingleton(telemetryWriter.Object);
services.AddTransient<BodyLoggerMiddleware>();
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Azureblue.ApplicationInsights.RequestLogging;
using FluentAssertions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Text.Json;
Expand All @@ -13,8 +14,14 @@ public class SensitiveDataFilterTests
public void Should_mask_tokens_with_sensitive_data_from_json()
{
// Arrange
var bodyLoggerOptions = new BodyLoggerOptions
{
PropertyNamesWithSensitiveData = new List<string>() { "token" },
SensitiveDataRegexes = new List<string>()
};

var jsonWithToken = JsonSerializer.Serialize(new { token = "some-super-secret-token" });
var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet<string> { "token" }, regexesForSensitiveValues: Array.Empty<string>());
var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions));

// Act
var result = filter.RemoveSensitiveData(jsonWithToken);
Expand All @@ -28,8 +35,14 @@ public void Should_mask_tokens_with_sensitive_data_from_json()
public void Should_mask_tokens_with_sensitive_data_from_nested_object_json()
{
// Arrange
var bodyLoggerOptions = new BodyLoggerOptions
{
PropertyNamesWithSensitiveData = new List<string>() { "password" },
SensitiveDataRegexes = new List<string>()
};

var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { password = "some-super-secret-token" } });
var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet<string> { "password" }, regexesForSensitiveValues: Array.Empty<string>());
var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions));

// Act
var result = filter.RemoveSensitiveData(jsonWithToken);
Expand All @@ -43,8 +56,14 @@ public void Should_mask_tokens_with_sensitive_data_from_nested_object_json()
public void Should_mask_tokens_with_sensitive_data_even_if_its_not_equal_match_json()
{
// Arrange
var bodyLoggerOptions = new BodyLoggerOptions
{
PropertyNamesWithSensitiveData = new List<string>() { "password" },
SensitiveDataRegexes = new List<string>()
};

var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { userPassword = "some-super-secret-token" } });
var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet<string> { "password" }, regexesForSensitiveValues: Array.Empty<string>());
var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions));

// Act
var result = filter.RemoveSensitiveData(jsonWithToken);
Expand All @@ -61,8 +80,14 @@ public void Should_mask_tokens_with_sensitive_data_even_if_its_not_equal_match_j
public void Should_mask_values_based_on_regex()
{
// Arrange
var bodyLoggerOptions = new BodyLoggerOptions
{
PropertyNamesWithSensitiveData = new List<string>() { "password" },
SensitiveDataRegexes = new List<string> { CreditCardRegex }
};

var jsonWithToken = JsonSerializer.Serialize(new { someObject = new { randomTokenName = SampleCreditCardNumber } });
var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet<string> { "password" }, regexesForSensitiveValues: new List<string> { CreditCardRegex });
var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions));

// Act
var result = filter.RemoveSensitiveData(jsonWithToken);
Expand All @@ -76,8 +101,14 @@ public void Should_mask_values_based_on_regex()
public void SensitiveDataFilter_should_remove_creditcard_number_from_plain_text_if_configured()
{
// Arrange
var bodyLoggerOptions = new BodyLoggerOptions
{
PropertyNamesWithSensitiveData = new List<string>() { "token" },
SensitiveDataRegexes = new List<string> { CreditCardRegex }
};

var plainTextWithToken = $"token: some-not-so-{SampleCreditCardNumber}secret-token-but-with-cc-inside";
var filter = new SensitiveDataFilter(sensitiveDataPropertyKeys: new HashSet<string> { "token" }, regexesForSensitiveValues: new List<string> { CreditCardRegex });
var filter = new SensitiveDataFilter(Options.Create(bodyLoggerOptions));

// Act
var result = filter.RemoveSensitiveData(plainTextWithToken);
Expand Down
Loading