Violation Reports

Lib.AspNetCore.Security provides middlewares which can receive violation reports for following security headers:

  • Content-Security-Policy (ContentSecurityPolicyReportingMiddleware)
  • Expect-CT (ExpectCtReportingMiddleware)

The middlewares can be added to the pipeline with MapContentSecurityPolicyReporting and MapExpectCtReporting extension methods.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseSecurityHeaders(builder =>
    {
        builder.WithCsp(
            ...
            reportUri: "/report-csp"
        )
        .WithReportOnlyExpectCt("https://example.com/report-ct")
        ...;
    })
    .MapContentSecurityPolicyReporting("/report-csp")
    .MapExpectCtReporting("/report-ct");

    ...
}

There are also similar extension methods which can be used with endpoint routing.

public void Configure(IApplicationBuilder app)
{
    ...

    app.UseEndpoints(endpoints =>
    {
        ...
        endpoints.MapContentSecurityPolicyReporting("/report-csp");
        endpoints.MapExpectCtReporting("/report-ct");
        ...
    });

    ...
}

Underneath the covers the middlewares will look for ISecurityHeadersReportingService service implementation, which might look like this:

public class LoggerSecurityHeadersReportingService : ISecurityHeadersReportingService
{
    private readonly ILogger _logger;

    public LoggerSecurityHeadersReportingService(ILogger<ISecurityHeadersReportingService> logger)
    {
        _logger = logger;
    }

    public Task OnContentSecurityPolicyViolationAsync(ContentSecurityPolicyViolationReport report)
    {
        _logger.LogWarning("Content Security Policy Violation: Document: {DocumentUri} | Resource: {BlockedUri} | Directive: {ViolatedDirective} | Disposition: {Disposition}",
            report.DocumentUri,
            report.BlockedUri,
            report.ViolatedDirective,
            report.Disposition);

        return Task.FromResult(0);
    }

    public Task OnExpectCtViolationAsync(ExpectCtViolationReport report)
    {
        _logger.LogWarning("Expect-CT Violation: Failure Date: {FailureDate} UTC | Effective Expiration Date: {EffectiveExpirationDate} UTC | Host: {Host} | Port: {Port}",
            report.FailureDate.ToUniversalTime(),
            report.EffectiveExpirationDate.ToUniversalTime(),
            report.Hostname,
            report.Port);

        return Task.FromResult(0);
    }
}

Service must be registered in the services collection during configuration, for example:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ISecurityHeadersReportingService, LoggerSecurityHeadersReportingService>();
    ...
}
Back to top Copyright © 2016 - 2023 Tomasz Pęczek