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

Add support for content security policy #6001

Open
javiercn opened this issue Aug 29, 2017 · 15 comments
Open

Add support for content security policy #6001

javiercn opened this issue Aug 29, 2017 · 15 comments
Labels
affected-medium This issue impacts approximately half of our customers area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware enhancement This issue represents an ask for new feature or an enhancement to an existing one Needs: Design This issue requires design work before implementating. severity-minor This label is used by an internal tool
Milestone

Comments

@javiercn
Copy link
Member

This is a placeholder issue.

Similar to the support that we have for CORS in APIs, we should have support for Content Security Policy to make sites safer by default.
Support for CSP would be policy based, similar to the one we offer for CORS.

Usage from middleware

ConfigureServices(IServiceCollection services)
{
    ...
    services.AddCsp();
    ...
}
Configure(IApplicationBuilder app)
{
    ...
    app.UseCsp();
    ...
}

Usage from MVC

ConfigureServices(IServiceCollection services)
{
    ...
    services.AddMvc(); // Add MVC will call AddCsp similar to what we do for CORS today.
    ...
}
[EnableCsp]
public IActionResult Index()
{
    return View();
}

We will provide a default policy that limits content to your domain, defines best practices for HTTPS and will be set to report-only. This behavior can be switched per endpoint so that you can progressively enforce the policy one endpoint at a time.

References

https://en.wikipedia.org/wiki/Content_Security_Policy

https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP

https://www.w3.org/TR/CSP2/

http://caniuse.com/#search=content%20security%20policy

@Eilon Eilon removed their assignment Oct 1, 2018
@muratg
Copy link
Contributor

muratg commented Oct 16, 2018

We'll need a design for this guys.

@muratg
Copy link
Contributor

muratg commented Oct 16, 2018

cc @shirhatti

@jrestall
Copy link

jrestall commented Oct 19, 2018

I created a policy based Content Security Policy library to use on my own sites while waiting for this support in the core libraries. Since content security policy support is now planned for 3.0, it might help you with the design discussion. I also followed your standards on the off chance you could use any of the code for this issue.

Code

Microsoft.AspNetCore.Csp
Microsoft.AspNetCore.Mvc.Csp

Samples

CspSample
CspSample.Mvc

public void ConfigureServices(IServiceCollection services)
{
    services.AddCsp(options =>
    {
        options.AddPolicy("Policy1", policy => policy
            .AddDefaultSrc(src =>
            {
                src.AllowSchema(CspDirectiveSchemas.Http);
                src.AllowSchema(CspDirectiveSchemas.Https);
                src.AllowSelf();
                src.AllowEval();
                src.AllowHash("sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=");
            })
            .AddScriptSrc(src => src.AddNonce())
            .AddStyleSrc(src => src.AddNonce())
            .ReportUri("/csp-reports")
            .ReportTo("csp-reports")
            .AddManifestSrc(src =>
            {
                src.AllowHost("http://*.example.com");
            })
            .ReportOnly()
        );

        options.AddPolicy("Policy2", policy =>
            policy.AddDefaultSrc(src => src.AllowNone().AddNonce())
        );

        options.AddPolicy("BetaUsers", policy =>
            policy.AddDefaultSrc(src => src.AllowHost("beta-testers.example.org"))
        );
    });

    services.AddMvc()
        .AddCspReportMediaType();

    services.AddMvcCore().AddCsp();

    services.AddScoped<IConfigureOptions<CspOptions>, TrialUserSrc>();
}

public class TrialUserSrc :  IConfigureOptions<CspOptions>
{
    public void Configure (CspOptions options)
    {
        if (context.User.HasClaim(c => c.Type == ClaimTypes.TrialUser))
        {
            var currentPolicy = options.GetPolicy("Policy1");
	    currentPolicy.Append(policy => 
                policy.AddDefaultSrc(src => src.AllowHost("trial.company.com"))
            );
        }
    }
}

Configuration with MVC Attributes

  • AppendCsp and OverrideCsp are optional attributes that modify the main policy on a per action basis.
[EnableCsp("Policy1", "Policy2")]
[AppendCsp("BetaUsers", Targets = "Policy1, Policy2")]
[OverrideCsp("BetaUsers")]
public IActionResult EnablePolicy1And2()
{
    ...
}

[DisableCsp]
public IActionResult Disabled()
{
    ...
}

Default Content-Security-Policy

This is the default policy I'm using:

    public class CspOptions
    {
        // Default Content-Security-Policy:
        //     default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:;
        //     object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
        private static readonly ContentSecurityPolicy DefaultContentSecurityPolicy

Tag Helpers

CspMetaTagHelper - Adds the content security policies as meta tags to the page.

<meta http-equiv="Content-Security-Policy" />

CspNonceTagHelper - Adds a nonce to script or style tags and automatically ensures a nonce is returned in the HTTP header.

CspGenerateHashTagHelper - Automatically generates hashes for inline scripts and styles and ensures the hashes are in the HTTP header.

<style asp-add-nonce="true" asp-generate-hash="true">
    p {
        color: #0000ff;
    }
</style>
<script asp-add-nonce="true" asp-generate-hash="true" asp-generate-hash-algorithms="HashAlgorithms.SHA256 | HashAlgorithms.SHA512">
    console.log("I'm a script that will be hashed dynamically.");
</script>

CspPluginTypeTagHelper - Automatically adds the used plugin types to the content security policy.

<embed asp-type="application/testplugintype2" />

CspFallBackTagHelper - Generates CSP hashes for the inline scripts that are generated when using asp-fallback-href or asp-fallback-src.

CspSubresourceIntegrityTagHelper - Automatically generates SRI hashes for the remote scripts using a local fallback script.

<link href="https://ajax.aspnetcdn.com/ajax/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"
      asp-fallback-href="~/lib/bootstrap/css/bootstrap.min.css"
      asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute"
      asp-subresource-integrity="true"
      asp-subresource-integrity-algorithms="HashAlgorithms.SHA256 | HashAlgorithms.SHA384 | HashAlgorithms.SHA512" />

CSP Report Support

  • CspReportRequest model

  • Added 'application/csp-report' media type support.

/// <summary>
/// Adds the 'application/csp-report' media type to the JSON input formatter so that csp reports can be received.
/// </summary>
/// <param name="builder">The <see cref="IServiceCollection" /> to add services to.</param>
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns>
public static IMvcBuilder AddCspReportMediaType(this IMvcBuilder builder)

cc @sebastienros - When this feature lands in 3.0 I'll implement CSP for Orchard Core 🎉

@javiercn
Copy link
Member Author

@jrestall Your approach is pretty solid. It's pretty much what I had in mind. I have some ideas on how to better integrate this with Razor, but the foundation is solid.

The way I see this, there will be a core library (similar to what we have for CORS) and then some MVC specific glue/enhancements/opinions.

In particular, I think it might be better to specify the policy as a Razor directive as its very resource specific. In many actions you don't have the ability to know what's going to be rendered. By doing it as a razor directive it can be something that you put on a _viewStart, _viewImports (not really sure which one of them yet) or simply at the start of your page or view.

That way the policy lives close to the resources, regarding hashes and things like that I would have to think more about this. One thing that I'm concern is the size of the policy on the header growing to a significant size, so I'm more inclined to use/recommend a different approach where you hoist the inline-scripts into js files for most cases.

I think that you are on point with the need to append to an initial policy and to completely override it in some cases.

Having a default policy is also great, but the default for the system should be to simply report so that you can start changing the code base to enforce the policy.

@aspnet-hello aspnet-hello transferred this issue from aspnet/BasicMiddleware Dec 19, 2018
@aspnet-hello aspnet-hello added this to the 3.0.0 milestone Dec 19, 2018
@aspnet-hello aspnet-hello added area-middleware Needs: Design This issue requires design work before implementating. labels Dec 19, 2018
@shirhatti
Copy link
Contributor

@mkArtakMSFT @javiercn Is this still happening in 3.0?

@ulrichb
Copy link

ulrichb commented Mar 19, 2019

Please don't forget about the validation summary (inline style-element) mentioned in #4817 (comment).

https://github.com/aspnet/AspNetCore/blob/bcead68f0cebf53c1c8fe4c1015cc6961f5a757c/src/Mvc/Mvc.ViewFeatures/src/DefaultHtmlGenerator.cs#L24

@chrisdpratt
Copy link

Interesting that no one has mentioned NWebSec. This library started life adding much needed security enhancements to ASP.NET MVC, and now support ASP.NET Core as well. There's already a pretty complete CSP implementation here, so at the very least, it might be worth referencing.

https://docs.nwebsec.com/en/latest/nwebsec/libraries.html

@joeaudette
Copy link

I'm looking forward to this being part of the aspnet core stack as well. I've experimented a bit with NWebSec but it seems it has not been updated in over a year, issues go unanswered and even their SSL cert for their website expired in Feb 2019 and they have not done anything about it. Seems like an abandoned project to me. https://www.nwebsec.com/

@nbarbettini
Copy link
Member

nbarbettini commented Apr 2, 2020

NWebSec is solid, but as @joeaudette said it's under-maintained right now. I would love to see something like @jrestall's approach built in.

NWebSec puts everything into Configure, but it would be easier to compose with things like the Options pattern if configuration happened in ConfigureServices like in James' example.

@aaronshim
Copy link

Hi folks,
My colleague @salcho has been in contact with some of you for adding framework-level support of CSP for ASP.NET. We've created #24548 of our proposed changes, so we will welcome any feedback! Thank you!

salcho pushed a commit to salcho/AspLabs that referenced this issue Aug 13, 2020
Hello .NET community!

This PR adds Content Security Policy support for ASP.NET as middleware. CSP is a popular security mitigation against XSS and other injection vulnerabilities. CSP comes in many flavours, but we've chosen to add support for the most robust of them: nonce-based, strict-dynamic CSP.

Summary of the changes (Less than 80 chars)

* Allow configuration of whether CSP enabled in reporting or enforcement modes.
* Allows configuration of a report URI, for violation reports sent by the browser.
* CSP middleware generates a nonce-based, strict-dynamic policy.
* Middleware adds thepolicy to HTTP responses according to the configuration.
* Custom <script> TagHelper to set nonce attribute on script blocks automatically.
* Provides a default implementation of a CSP violation report collection endpoint.
* Example app that uses our CSP middleware and corresponding basic unit tests.
* With these tools, developers can enable CSP in reporting mode, collect reports and identify and refactor existing code that is incompatible with CSP from these reports. Finally, developers will be able to switch CSP to enforcing mode, which will provide a very robust defense against XSS.

Addresses dotnet/aspnetcore#6001

Co-authored with: Aaron Shim - aaronshim@google.com
@V4A001
Copy link

V4A001 commented Nov 5, 2020

Is this issue included: validation summary emitting style="display:none".
[Report Only] Refused to apply inline style because it violates the following Content

<div asp-validation-summary="All" class="text-danger"></div> <div class="text-danger validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>

@JunTaoLuo JunTaoLuo added affected-medium This issue impacts approximately half of our customers enhancement This issue represents an ask for new feature or an enhancement to an existing one labels Nov 11, 2020 — with ASP.NET Core Issue Ranking
@Ponant
Copy link
Contributor

Ponant commented Aug 13, 2021

@javiercn , I do not see a real benefit of having a csp as a directive. Rather, I think it is better to make the templates more Csp compliant for those who already are implementing Csp (with or without a library) and who may find themselves in using unsafe keywords in the Csp directive set:

One example is the style in the default generator as mentioned above

private const string HiddenListItem = @"<li style=""display:none""></li>";

Another one is the injection of javascript during development, see @damienbod here #34428

Regarding the library, from my own experience with Csp at least, I see most benefit in having enable/disable attributes, filters and a global Csp/ReportOnly. For Spa's, I don't know yet, so probably meta tags with hashes (?).

@misterspeedy
Copy link

Please don't forget about the validation summary (inline style-element) mentioned in #4817 (comment).

Narrator: They did forget about it.

@Ponant
Copy link
Contributor

Ponant commented Sep 13, 2021

I created a library for CSP because we needed it in production apps and existing libraries including NWebsec did not fully fulfill our conditions. It is based on a pragmatic and performance-oriented design philosophy which I believe is worth sharing after a brief exchange with @damienbod here #34428. This lead us to introduce the concept of a CSP Policy Group. This class encompasses the Content-Security-Policy and Content-Security-Policy-Report-Only headers in one entity, because they can and should be used in tandem.

So I go along by copy pasting some text, and you can get extensive details here
https://github.com/Ponant/Galebra.Security/tree/master/src/Galebra.Security.Headers.Csp , in particular the design section, together with a bunch of references. Critics and/or questions are always welcome.

Get Started

All terminology is explained after. The library does not use EndPoint routing, so you can invoke the UseContentSecurityPolicy
middleware before or after UseRouting.

app.UseContentSecurityPolicy();

It can be placed before UseStaticFiles if you need CSP headers to be delivered with peculiar content such as SVG.

You configure CSP via appsettings.json or via an Action in Program.cs.

When using appsetting.json:

using Galebra.Security.Headers.Csp;

builder.Services.AddContentSecurityPolicy(builder.Configuration.GetSection("Csp"));

There are two services registered, a Singleton, essentially holding the configuration, and a Scoped service for nonce generation.

In the following, three policy groups are registered:

  "Csp": {
    "IsDisabled": false,//default: Will apply the default policy everywhere until overriden by attributes or filters
    "PolicyGroups": {
      "PolicyGroup1": {
        "Csp": {
          "Fixed": "default-src 'none' 'sha256-RFWPLDbv2BY+rCkDzsE+0fr8ylGr2R2faWMhq4lfEQc=';script-src 'self'"
        },
        "IsDefault": false,
        "NumberOfNonceBytes": 16//default
      },
      "PolicyGroup2": {
        "Csp": {
          "Fixed": "default-src 'self';base-uri 'self';form-action 'self';object-src;frame-ancestors;connect-src ws://localhost:65412",
          "Nonceable": [
            "style-src 'self'"
          ]
        },
        "CspReportOnly": {
          "Fixed": "default-src;form-action 'self';base-uri;object-src;frame-ancestors;sandbox",
          "Nonceable": [
            "style-src",
            "script-src"
          ]
        },
        "IsDefault": true,//default
        "NumberOfNonceBytes": 8
      },
      "PolicyGroup3": {
        "Csp": {
          "Nonceable": [
            "style-src"
          ]
        },
        "IsDefault": false,
        "NumberOfNonceBytes": 3
      }
    }
  },

The first policy group does not require nonces (hence fixed, see below) and only requires the Content-Security-Policy header to be set.
The second policy group configures the two headers, CSP and CSP-Report-Only, and requires nonces for each of these headers.
This policy is the default policy, IsDefault=true. The IsDisabled property in Line 1 is set to false (default),
which means that the default policy named PolicyGroup2 will be applied globally unless overridden by attributes or filters.
The third policy uses only nonces, for styles. The default value for nonce generation is 16 bytes.
We used connect-src ws://localhost:65412 in this example to allow /_framework/aspnetcore-browser-refresh.js to work properly.
Also, we disabled CSS Hot Reload in Visual Studio, see #36085, to avoid
a weak CSP configuration just for development.

Alternatively, you can configure everything in code:

builder.Services.AddContentSecurityPolicy(c =>
{
    c.IsDisabled = false;
    c.Add("Policy1", g =>
    {
        g.Csp.Fixed = "default-src 'self';connect-src ws://localhost:65412";
        g.Csp.Nonceable.Add("style-src 'self'");
        g.CspReportOnly.Nonceable.Add("script-src");
        g.IsDefault = true;
        g.NumberOfNonceBytes = 32;
    });
    c.Add("Policy2", g =>
    {
        g.Csp.Fixed = "default-src 'self';connect-src ws://localhost:65412";
        g.CspReportOnly.Fixed="default-src";
        g.IsDefault = false;
    });
});

Add nonces to the body by importing the TagHelpers

@addTagHelper *, Galebra.Security.Headers.Csp

And add to styles, scripts or link tags the TagHelper:

nonce-add=true

For example, for PolicyGroup3, that restricts you to use only nonced styles,
you would allow loading bootstrap like so:

    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" nonce-add=true/>

As you may agree, this logical structure actually is powerful.

Design Philosophy and introduction

The following design principles, detailed below, have been followed:

  • CSP configuration is well suited in appsettings.json because you need to store long strings
  • Configuration via Action should also be possible in Program.cs
  • Support multiple policies to use in different parts of the website
  • Enable and Disable attributes in pages or actions or controllers
  • Enable and Disable Filters for folders in razor pages
  • Developper provides a default, global policy, and can override
  • Possibility to apply the default policy everywhere, and override for parts of the website,
    or have no policy applied globally and set them on specific parts only
  • Support CSP and a CSP-Report-Only headers simultaneously, each with a different set of policy directives
  • Optimize nonce generation for script, style, and link tags
  • Use the latest recommendations for random number generations
  • Optimize string generation for common CSP string lengths
  • Add CSP to headers by using the key already existing in HttpContext to avoid memory allocation
  • Each policy is, at the end, a long string.
    This string can be either static (fixed) or generated newly on each request if nonces are required.

Consider the following arguments. CSP is a set of two headers, whose names can be:

  • Content-Security-Policy
  • Content-Security-Policy-Report-Only

Each policy in those headers is defined by an ordered set of directives.
Each directive is a name/value pair; name is non-empty, but value may be empty.
For example, script-src is a directive's name and the value can be, for instance, 'self' or a url or a set of these.
Another directive can be default-src 'none', where default-src is another directive name.
The directives forming a policy are separated by semicolons.
For this example, the Content Security Policy would be the header:

Content-Security-Policy: default-src 'none';script-src 'self'

which is equivalent to the shorter version

Content-Security-Policy: default-src;script-src 'self'

In theory, you can have multiple CSP policies for the same header name
in the same response header; however, we believe this should not be recommended because it makes your policy more convoluted
and rather highlights a design flaw, notwithstanding that you send more bytes to the user's browser. Consequently, the library
outputs only one CSP header for a given header name.
In practice, we assign the value for the header key (name) rather than adding a new item in the dictionary.
This also has the consequence of efficient write.

So, with this library, you cannot have the following:

Content-Security-Policy: Policy1
Content-Security-Policy: Policy2

The CspPolicyGroup class

However, you can have both a CSP and a CSP-Report-Only policy, and usually this is recommended.
Some libraries do not support this configuration. This library does. For example you can do something like this:

Content-Security-Policy: default-src 'self'
Content-Security-Policy-Report-Only: default-src;style-src 'self'

In this scenario, the website would run without issues if, loosely speaking, all styles and scripts are loaded from the server
('self'), but the browser will report to you what would break if you disable scripts ('none') and other fetch directives,
except for styles which use 'self'.
Thus, this allows you to enforce a policy and at the same time fine-tune another one which ultimately will become
the enforcing policy when you are ready.

Allowing for both CSP and CSP-Report-Only headers to coexist introduces the CspPolicyGroup class.
It is this group class that you use to configure your policies. This class contains two properties, Csp and CspReportOnly, each of
which is a CspPolicy class. You can leave one of these properties empty; for example if you want to have only browser reports,
you would build only the property CspReportOnly.

The CspPolicy class and Nonce TagHelper

The usual route to library design is to use the so-called fluent-api. This gives elegant code,
but with CSP this is unnecessary complication and makes your Program.cs (or Startup.cs) rather long.
In addition, CSP configuration ultimately boils down to outputting one or two strings in the headers,
plus the possibility of nonces in those headers and pages.
A developer will ultimately look at the CSP output in the browser's tools
to see if the formatting is as expected and nonces properly generated and positioned.
There is already a lot of resources and services in the pipeline, so we decided to keep it simple and focus on performance.

This led us to the following observation. A CSP header value is always divided into two groups.
The first group is a fixed, possibly empty, string, i.e. a string that does not change upon requests on a given page,
and another string that is dynamically generated upon each request to include one or more nonces.
Therefore the CspPolicy class has two public properties, a string Fixed and a list of strings called Nonceable.

For example, the policy:

default-src;style-src 'self'

would be set as a CspPolicy.Fixed string because a nonce is not required. In appsettings.json, this would be:

"Fixed": "default-src;style-src 'self'",

A sha256-myshacode, if needed, would be included in the Fixed string.

If, now, you want to have this policy, but in addition produce a nonce for styles, then you would need to split your string
and populate the CspPolicy.Nonceable list. In appsettings.json, the split would be like this:

"Fixed": "default-src",
"Nonceable": [
"style-src 'self'"
]

The style-src is here short, but generally is longer to include for example urls from a Bootstrap CDN. The most important is to
identify the directive's name, here style-src.

To use the nonce on the style in this example, you would invoke the Tag Helper nonce-add, e.g.

<style nonce-add=true>
.myclass{
    background:lightgreen;
}
</style>
<h4 class="myclass">I am lightgreen, thank you nonce!</h4>

When you use a nonce, common libraries are confined to the script and style tags, but link tags are also possible.
Nonce generation defaults to the spec-recommended 16 bytes, which gives 256^16=2^128 possibilities,
or a 22 long web-encoded base64 string. You can override this with the property CspPolicyGroup.NumberOfNonceBytes,
e.g. in appsettings.json, and the nonce will apply to the entire group.

"NumberOfNonceBytes": 8

Multiple Policies, Attributes, Filters and default CspPolicyGroup

When you implement CSP on a website, often you need several CspPolicyGroup objects depending on the page where the user lands.
For example, you would have a global CSP policy on all pages, but when processing a payment on a page or Razor Pages folder,
or a Controller, you will want another CSP policy (for example to accept connections to a payment API such as PayPal or Stripe).
This library allows you to configure many policies and invoke them when needed, through attributes and filters.

When you use the library, unless you override the default described below, the default CspPolicyGroup
is applied to all pages as soon as you inject the Middleware in the pipeline.

You can apply a given policy to an entire Folder in Razor Pages, e.g. in the Movies folder:

//Apply on specific folders
builder.Services.AddRazorPages(options =>
{
    options.Conventions.AddFolderApplicationModelConvention(
        "/Movies",
                model => model.Filters.Add(new EnableCspPageFilter { PolicyGroupName = "PolicyGroup1" }));
});

You can also disable CSP in a folder:

 model => model.Filters.Add(new DisableCspPageFilter { EnforceMode = false }));

Where EnforceMode is true by default and is discussed below.

In areas, you could do something like this:

    options.Conventions.AddAreaFolderApplicationModelConvention("Identity", "/Account",
     model => model.Filters.Add(new EnableCspPageFilter { PolicyGroupName = "PolicyGroup1" }));

    options.Conventions.AddAreaPageApplicationModelConvention("Identity", "/Account/Manage/ChangePassword",
        model => model.Filters.Add(new EnableCspPageFilter { PolicyGroupName = "PolicyGroup3" }));

In a Razor Page or Action or Controller, you can override the default CspPolicyGroup with an attribute:

[EnableCsp(PolicyGroupName="PolicyGroup1")]
[DisableCsp]

The [DisableCsp] always wins unless you set the init property DisableCsp.EnforceMode to false.
The enforcement rule is useful in a scenario where an entire folder or a controller needs to have CSP disabled on all routes
except for those where the enable attribute is present. For example, in the following we use the DisableCspPageFilter
to disable CSP in the Movies folder:

builder.Services.AddRazorPages(options =>
{
    options.Conventions.AddFolderApplicationModelConvention(
        "/Movies",
    model => model.Filters.Add(new DisableCspPageFilter { EnforceMode = false }));
});

Because we have set EnforceMode = false, we can set CSP on a page inside the Movies folder with an attribute,
e.g. in Movies/index [EnableCsp(PolicyGroupName = "PolicyGroup3")]. The same applies for a controller; you would disable CSP
with EnforceMode=false and use the EnableCsp attribute on an action:

[DisableCsp(EnforceMode = false)]
public class BooksController : Controller
{
    public ActionResult Index()
    {
        //CSP is disabled here
        return View();
    }

    // GET: BooksController/Details/5
    [EnableCsp(PolicyGroupName ="PolicyGroup3")]
    public ActionResult Details(int id)
    {
        //CSP works here owing to EnforceMode=false
        return View();
    }
}

IsDisabled global boolean

By default, the library applies the default CspPolicyGroup to all delivered pages until overwritten by attributes or filters.
You can override this global behaviour in Program.cs or in appsettings.json where you can set at the top level
"IsDisabled": true,. This will result in CSP not being applied globally, at all, until you invoke it via attributes or filters.

@amcasey amcasey added area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware and removed area-runtime labels Jun 2, 2023
@niemyjski
Copy link

This would be really nice to be built in. Two other libraries support this as well https://github.com/andrewlock/NetEscapades.AspNetCore.SecurityHeaders and https://github.com/juunas11/aspnetcore-security-headers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affected-medium This issue impacts approximately half of our customers area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware enhancement This issue represents an ask for new feature or an enhancement to an existing one Needs: Design This issue requires design work before implementating. severity-minor This label is used by an internal tool
Projects
None yet
Development

No branches or pull requests