extensions icon indicating copy to clipboard operation
extensions copied to clipboard

Sensitive records aren't redacted when used in IEnumerable<T> in a logging method

Open xakep139 opened this issue 2 years ago • 3 comments

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

xakep139 avatar Nov 02 '23 17:11 xakep139

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.

geeknoid avatar Nov 02 '23 17:11 geeknoid

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)

joperezr avatar Nov 06 '23 17:11 joperezr

This wasn't affected by #4658 at all. The logic there doesn't check IEnumerable

xakep139 avatar Nov 08 '23 07:11 xakep139