franzo franzo - 1 month ago 9
ASP.NET (C#) Question

Accessing Content Security Policy violation reports posted to ASP.Net

For example if you have a CSP like

default-src 'self'; report-uri /CspViolationReport

and if
/CspViolationReport
is handled by ASP.Net, how do you access the CSP violation report that is posted?

We expect to find some JSON posted, e.g. http://www.w3.org/TR/CSP11/#example-violation-report

When you inspect
Request.Form
, there are no keys, and there is no evidence of it in
Request.ServerVariables["ALL_RAW"]
, but
Request.ServerVariables["HTTP_METHOD"]
is "POST".

Intercepting the POST with Fiddler, you can see that the JSON is certainly being posted, but .Net doesn't seem to let you see it.

Answer

Here's a way, inspired by http://muaz-khan.blogspot.co.nz/2012/06/exploring-csp-content-security-policy.html, thanks!

void ProcessCspValidationReport() {
    Request.InputStream.Position = 0;
    using (StreamReader inputStream = new StreamReader(Request.InputStream))
    {
        string s = inputStream.ReadToEnd();
        if (!string.IsNullOrWhiteSpace(s))
        {
            CspPost cspPost = JsonConvert.DeserializeObject<CspPost>(s);
            //now you can access properties of cspPost.CspReport
        }
    }
}

class CspPost
{
    [JsonProperty("csp-report")]
    public CspReport CspReport { get; set; }
}

class CspReport
{
    [JsonProperty("document-uri")]
    public string DocumentUri { get; set; }

    [JsonProperty("referrer")]
    public string Referrer { get; set; }

    [JsonProperty("effective-directive")]
    public string EffectiveDirective { get; set; }

    [JsonProperty("violated-directive")]
    public string ViolatedDirective { get; set; }

    [JsonProperty("original-policy")]
    public string OriginalPolicy { get; set; }

    [JsonProperty("blocked-uri")]
    public string BlockedUri { get; set; }

    [JsonProperty("source-file")]
    public string SourceFile { get; set; }

    [JsonProperty("line-number")]
    public int LineNumber { get; set; }

    [JsonProperty("column-number")]
    public int ColumnNumber { get; set; }

    [JsonProperty("status-code")]
    public string StatusCode { get; set; }
}