extensions
extensions copied to clipboard
Sensitive records aren't redacted when used in IEnumerable<T> in a logging method
Description
The source-generated implementation of M1 (see reproduction steps) won't redact or report an error and will emit sensitive data as-is.
Reproduction Steps
Consider this example:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter)]
internal sealed class PrivateDataAttribute : DataClassificationAttribute
{
public static DataClassification Classification => new("ComplianceTaxonomy", "ContosoClassification");
public PrivateDataAttribute() : base(Classification)
{
}
}
record A([property: PrivateData] string SensitiveProperty);
record B(IEnumerable<A> collection);
internal static partial class Log
{
[LoggerMessage(LogLevel.Information, "Something...")]
static partial void M1(ILogger logger, [LogProperties] B param);
}
Then create an ILogger and call the method:
using var loggerFactory =
LoggerFactory.Create(builder =>
{
builder.EnableRedaction();
builder.AddJsonConsole();
builder.Services.AddRedaction(x => x.SetRedactor<ErasingRedactor>(new DataClassificationSet(PrivateDataAttribute.Classification)));
});
var logger = loggerFactory.CreateLogger("MyDemoLogger");
Log.M1(logger, new B([new A("Sensitive value here!")]));
Expected behavior
An error emitted by the source-gen or redaction happenned.
Actual behavior
The current implementation emits "param.collection": "[\u0022A { SensitiveProperty = Sensitive value here! }\u0022]" with a JSON console exporter.
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response
This is by design.
The intent here is that redaction will occur on the final string. not on the individual items in the enumeration. That is, we do Redact(Stringify(Enumerable)) and not Stringify(IEnumerable(Redact)) if you get what I mean.
So you need to apply a data classification on the log method parameter and that will be redacted, or on the IEnumerable property.
Just to make sure I'm following, this wasn't really fixed by https://github.com/dotnet/extensions/pull/4658 but instead that PR just started to make it so we don't silently fail and throw an error, but in the end the real fix should be in Roslyn, correct?
(Since I'm pretty sure this is the case, I'll go ahead and push the milestone of this issue to post-GA as we have gotten the piece we needed for GA)
This wasn't affected by #4658 at all. The logic there doesn't check IEnumerable