juunas11 / aspnetcore-security-headers Goto Github PK
View Code? Open in Web Editor NEWMiddleware for adding security headers to an ASP.NET Core application.
License: MIT License
Middleware for adding security headers to an ASP.NET Core application.
License: MIT License
The X-Xss-Protection
header supports a report uri: https://docs.report-uri.com/setup/xxp/
Can this be added to XXssProtectionOptions
?
In asp.net core Hsts already included in Microsoft.AspNetCore.HttpsPolicy
Maybe HstsMiddleware should be excluded from next released of this project.
I seen, that this package supports versions earlier than 2.2.0 of asp.net core, but probably conditional compilation of obsolete attributes with redirecting call to Microsoft.AspNetCore.HttpsPolicy will help.
Hi! We're using your package in a couple of our ASP.NET Core 2.0 apps, and came across errors like this in our logs:
System.ArgumentException: An item with the same key has already been added. Key: Content-Security-Policy
at System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(Object key)
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameResponseHeaders.AddValueFast(String key, StringValues value)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.FrameHeaders.System.Collections.Generic.IDictionary<System.String,Microsoft.Extensions.Primitives.StringValues>.Add(String key, StringValues value)
at Joonasw.AspNetCore.SecurityHeaders.Csp.CspMiddleware.<Invoke>d__5.MoveNext()
We are also using the UseStatusCodePagesWithReExecute
middleware in our pipeline to handle Status Codes. After some debugging, we found that:
UseStatusCodePagesWithReExecute
, then the Exception is thrown if the UseStatusCodePagesWithReExecute
is invoked (i.e. when a Controller Action uses StatusCode
), and is not thrown otherwise.UseStatusCodePagesWithReExecute
then no Exception is thrown.Since the UseStatusCodePagesWithReExecute
middleware causes subsequent middleware to be invoked again, we deduced that the CSP middleware must be getting invoked twice, and is trying to add the Content-Security-Policy
header again, causing the exception to be thrown. We found that in your package, the CspMiddleware
adds to the Response Headers collection without first checking if the item already exists.
What would be your recommendation - should we add add the CSP middleware to our pipeline before UseStatusCodePagesWithReExecute
, or could you add a check in the middleware to only add the header if it is not already set?
First of all, thanks for providing this library, it works fine.
Currently, every response has the CSP header set which is not always desirable. Consider a web application with a mix of MVC/Razor and API controllers where only the MVC/Razor controllers are entry points for client browsers and the API is used by client browsers and other API-only clients. Since only browsers know what to do with and how to interpret a CSP header the API clients don't need that header, we could save a few bytes of network traffic.
One possible solution would be to add an extension point at
One approach would be to add an Events
object with callbacks similar to https://github.com/aspnet/Security/blob/ff9f145a8e89c9756ea12ff10c6d47f2f7eb345f/src/Microsoft.AspNetCore.Authentication.Cookies/Events/CookieAuthenticationEvents.cs to CspOptions. What do you think ?
With "report-uri" being deprecated, we should add support for the new "report-to" directive and header.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/report-uri
Is it possible to include "X-Content-Security-Policy" header?
Hi, and thanks for the great package!
This is a weird one.
Nuget version 4.0.1, ASP NET Core 6.
ViewImports:
@using WebUI
@namespace WebUI.Pages
@addTagHelper *, Joonasw.AspNetCore.SecurityHeaders
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.Extensions.Localization
Startup:
app.UseMiddleware<SecurityHeadersMiddleware>();
app.UseCsp(csp => {
csp.ByDefaultAllow.FromNowhere();
csp.AllowScripts
.FromSelf()
.AddNonce();
csp.AllowStyles
.FromSelf()
.AddNonce();
csp.AllowImages
.FromSelf();
csp.AllowFonts
.FromSelf();
});
....
services.AddCsp();
_Layout.cshtml (with nonce as title for testing):
<head>
<title>@Nonce.GetNonce()</title>
<script src="~/lib/jquery/dist/jquery.min.js" asp-add-nonce="true"></script>
Generated html:
<title>dCOv2X2ZpvsHAVQy4NPb4m2uslSe1azP+bdVjkbGDtk=</title>
<script src="/lib/jquery/dist/jquery.min.js" nonce=""></script>
I set a breakpoint to the NonceTagHelper Process and it actually hits, runs through the output.Attributes.Add("nonce", _nonceService.GetNonce());
and I tested that the _nonceService.GetNonce() actually returns the nonce.
So everything seems to work as intended, expect that the nonce is not output to html. I'm dumbstruck, especially when the breakpoint shows that the code is actually ran.
Would you happen to have any ideas?
Quoting dasmulli on Slack:
could also look into not adding the headers before the next steps of the pipeline, but rather registering a delegate somewhere in the response. this would enable for response type checking.. other than checking the request for known api paths etc.
Any chance of adding support for the prefetch-src
CSP? See https://w3c.github.io/webappsec-csp/#directive-prefetch-src
Hello!
Really nice extension. Installed it via Nuget. Need to get this working with internet explorer 11 and was wondering if you have any suggestion on how to get this working with the x-content-security header used by internet explorer?
I have one specific page with an inline script that is generating this error. Is there a way to allow unsafe-eval just for that script or page?
It would be great to be able to set the base-uri
directive on the CSP header.
Add IServiceCollection extensions that allow specifying the options for middleware in the typical Core fashion, e.g.:
services.AddCsp(o =>
{
o.AllowAny = true;
});
I'm trying to resolve a CSP error created by an iframe used in https://github.com/IdentityModel/oidc-client-js . I believe setting the frames value in the CSP to strict-dynamic and adding a nonce to that script will resolve my issue, but that option doesn't appear to be available for frames, only for scripts.
According to the Mozilla dev tools, its available for both
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#strict-dynamic
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src
Would you add/be willing to accept a PR for this?
This is the normal syntax
app.UseCsp(builder =>
{
builder.ByDefaultAllow
.FromSelf();
});
I need to be more flexible. How would I do this?
var cspBuilder = new Joonasw.AspNetCore.SecurityHeaders.Csp.Builder.CspBuilder();
cspBuilder.ByDefaultAllow.FromSelf();
if (cConfig.HashList != null)
{
foreach (var c in cConfig.HashList)
cspBuilder.AllowStyles.From(c);
}
app.UseCsp( ???? )
what replaces ????
Does asp-add-nonce="true" helper work for partials? In my project it doesn't seem to work.
It would be great if any inline script tag could be annotate with an attribute something like "asp-csp-hash". This could be implemented as a tag helper that automatically calculates the SHA hash of the script contents and adds to the CSP response header.
I don't know if it's too late to update the response header by this point in the middleware. I was thinking it could be done when the middleware stack unwinds if the response hasn't been sent yet.
Can we use nonce's with a SPA application? We don't have any Razor view to modify to add the asp-add-nonce
tag, instead, we somehow need the library to take the static files built by Webpack and modify them at runtime to add the nonce tokens.
Is this something this library can do?
Any idea on fixing the style in
<div asp-validation-summary="All" class="text-danger"></div>
The nonce tag helper can add a nonce to style
and script
tags, but not to div
elements. Are there any reasons why a nonce can't be added to div
elements? I have a few cases where div elements contains inline style where this could be useful. Would you accept a PR to add support for this?
Refused to load the stylesheet 'data:text/css;base64,LnN3YWdnZXItdWkgLnRvcGJhciB7CiAgICBiYWNrZ3JvdW5kOiAjMDEyYjViICFpbXBvcnRhbnQ7Cn0KCi5zd2FnZ2VyLXVpIC50b3BiYXIgLmRvd25sb2FkLXVybC13cmFwcGVyIHsKICAgIGRpc3BsYXk6IG5vbmUhaW1wb3J0YW50Owp9CgogICAgLnN3YWdnZXItdWkgLnRvcGJhciAuZG93bmxvYWQtdXJsLXdyYXBwZXIgLnNlbGVjdC1sYWJlbCB7CiAgICAgICAgY29sb3I6IHdoaXRlICFpbXBvcnRhbnQ7CiAgICB9CgogICAgICAgIC5zd2FnZ2VyLXVpIC50b3BiYXIgLmRvd25sb2FkLXVybC13cmFwcGVyIC5zZWxlY3QtbGFiZWwgc2VsZWN0IHsKICAgICAgICAgICAgYm9yZGVyLWNvbG9yOiAjMDUwOTE5ICFpbXBvcnRhbnQ7CiAgICAgICAgfQ...QwdWlJNk1sSXJmOS9rZFAxV2FWamhTLzNWKzB0TnZGVVpFeFVoSFAweWwxN0k1QXdPZnhlRWF6VmRIWVl1dDhxWkVZUTRwbGg1TjU5bmlDTEdLQlZrZXRCeUNZUGxRcUlwdGJMZ3ZvZFAydFJ2Zmpod1NEUkVUMlIxeHVNYmVoNFBkOFNyem5qY2ZPUVhCd1lURDVWVTZDWUl0WWVOei9nL1ZSY04vNTVwRGxrT1dDUTVaRGxrT1dDdzVaWDhUL0Fnd0FUS2p3UVpGUXZxNEFBQUFBU1VWT1JLNUNZSUk9Jykgbm8tcmVwZWF0OwogICAgICAgIHdpZHRoOiAxMTVweDsKICAgICAgICBoZWlnaHQ6IDQ4cHg7CiAgICAgICAgcGFkZGluZzogMCAhaW1wb3J0YW50OwogICAgfQoKICAgIC5zd2FnZ2VyLXVpIC5pbmZvIC50aXRsZSArIGEgewogICAgICAgIGRpc3BsYXk6IG5vbmU7CiAgICB9' because it violates the following Content Security Policy directive: "default-src *". Note that 'style-src-elem' was not explicitly set, so 'default-src' is used as a fallback.
Add support for all remaining and upcoming security headers. While some of the latest browsers now use CSP for things like X-Frame-Options, IE does not and would require the X-Frame-Options header to still be present. References #1
These headers would need to be configurable as well to pass all security checks on sites such as https://securityheaders.com and https://tools.geekflare.com.
Thanks
Could you make a preview package for Core 2.0?
When using IIS in a virtual application, the application path isn't added to the report URL.
I have the following route defined:
app.UseEndpoints(endpoints => {
endpoints.MapControllerRoute("Csp", "{area:exists}/{controller=Home}/{action=Index}/{id?}");
...
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
}
app.UseCsp(csp => {
// Various rules here
csp.ReportViolationsTo("/csp/report");
}
I have a CSP controller in an area named CSP:
When a violation occurs, it's sent to https://servername.com/csp/report
however running in IIS it needs to be https://servername.com/somepath/csp/report
My current workaround is to move the csp.ReportViolationsTo
inside OnSendingHeader
:
app.UseCsp(csp => {
// Various rules here
csp.OnSendingHeader = context => {
var path = new PathString($"{context.HttpContext.Request.PathBase}/csp/report");
csp.ReportViolationsTo(path);
context.ShouldNotSend = context.HttpContext.Request.Path.StartsWithSegments("/swagger");
return Task.CompletedTask;
};
}
However, that will reset the ReportViolations every time and is not ideal.
This is something that other areas of ASPNET Core already handles. For example, setting app.UseStatusCodePagesWithReExecute("/Error/{0}");
would properly redirect 404 error pages to https://servername.com/somepath/error/404
HstsOptions
should be refactored to use a Timespan
instead of an int
and may be immutable too:
var options = new HstsOptions(Timespan.FromDays(30), includeSubDomains: false, preload: false);
app.UseHsts(options);
It can often make sense to implement a report endpoint into the same .NET project that uses this library for setting the CSP-header. A CSP-report is a JSON-structure. It would be nice to have a pre-made object in this library we can serialize into out-of-the-box with easily accessable properties. Usage example:
[HttpPost]
public IActionResult ReportEndpoint(CspReport report)
{
Console.Log(report.DocumentUri.ToString());
Console.Log(report.ViolatedDirective);
Console.Log(report.BlockedUri.ToString());
return Ok();
}
I am generating a script dynamically in C# code, and I want to be able to provide the nonce. Is there a way to access the nonce's value in my C# code?
Hi there,
Great library, I noticed with asp.net core 2.1 that when I'm using your library that I need to fully qualify the name .UseHsts() method that asp.net core 2.1 uses
HstsBuilderExtensions.UseHsts(app);
I can't use
app.UseHsts();
Also I ran your sample app under tests, but I can't seem to see x-frame-options header when I run the app? I see it's using the appsettings config method ( which I can't find documentation on)
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' *.cloudflare.com *.disquscdn.com *.googleapis.com *.buttercms.com *.googleusercontent.com 'nonce-Tz8sqHeAjtkqmJZxqciT/YJzmu27Nqr7Y2WPwJMT+Cs='". Either the 'unsafe-inline' keyword, a hash ('sha256-U9tCTcgKy8M4xindppgbF+UxDlhaFqd2U2zGu0s19ik='), or a nonce ('nonce-...') is required to enable inline execution.
The Tag Helper doesn't apply the nonce to the following (among others)
<div background-image: url(@Html.GetResizedImageUrl(Model.FeaturedImage, 1200, 250, FitType.Crop));" asp-add-nonce="true"><!-- stuff --></div>
It would be useful to be able to enable 'report-sample' property on any directive. This sends a 40 byte sample of the script or style that broke the directive (see https://csper.io/blog/an-introduction-to-report-uri for more details).
Hi, I have this working with Blazor, however I cant see how or if its possible to implement Nonces in the blazor client, as the blazor client wouldn't know the Nonce value, as the client and server are separate.
Just wanted to check that my assumption is correct?. which means I have to use
csp.AllowStyles
.FromSelf()
.AllowUnsafeInline()
It looks like you are adding headers before calling next() in the middleware. This means that any middleware registered after the security header middleware does not have a chance to preempt the middleware and add their own more appropriate headers.
Have you considered registering an action to be invoked on Response.OnStarting? This would allow for you to check to see if any other middleware closer to the response generation had already added the header.
Hi
I followed your guide on the readme but I cant get the nonce to work, unsafe inline is working fine.
I have created a testproject where I add the
services.AddCsp(nonceByteAmount: 32);
in the configureservices section and the
app.usecsp in the Configure section with .AddNonce()
added the taghelper in the viewimport
and added the asp-add-nonce="true" to the script tag.
It also get the auto completion for that tag.
but when i start the website i get an error that it violates the csp rules because the inline doesnt have a nonce.
I added the nonce in the index.cshtml
here the testproject to download : https://www.dropbox.com/sh/9ykavf5c0kik6j7/AABNY-Tsnm8WK3tftgw7lj9Sa?dl=0
Add Antiforgery Token to report violations post method.
Hi,
According to sereval security audits, the "Feature Policy" header is obsolete and the new name is "Permissions-Policy".
https://httptoolkit.com/blog/renaming-feature-policy-to-permissions-policy/
I would like to configure CSP in the appsettings.json but as the title suggests also prevent adding the header for some requests that don't make sense (similar to how it's described in the docs to omit the response header on API requests).
I set the configuration using
services.Configure<CspOptions>(configuration.GetSection("Csp"));
and in order to configure OnSendingHeader
in the UseCsp
:
app.UseCsp(cspBuilder =>
{
cspBuilder.OnSendingHeader = ctx =>
{
ctx.ShouldNotSend = /* boolean condition */
return Task.Completed;
}
});
which overrides the CSP options defined in the appsettings.json which IMO is a bug. If the options are already configured, the UseCsp
call with the builder parameter should not generate empty CSP which it does.
Hi,
I've currently implemented this on my .NET core website in Startup.cs like this:
csp.AllowScripts.FromSelf()
.AddNonce()
.WithStrictDynamic()
.From("....")
Editors have the ability to add scripts via a content management system, these then get rendered onto the frontend as raw HTML. The CSP header is blocking these (correctly) as they do not have the nonce attached.
They are rendered in the cshtml View like this:
@Html.Raw(Model.Script)
We have access to the value (as a string) prior to it being rendered so we can manipulate beforehand. Is there a way of appending the nonce added in Startup.cs to this string?
The scripts the editors can add can vary from something like:
<script type="text/javascript" src="xyz.com/tracking.js" />
or
<script>console.log('hello')</script>
My question is, is there a way to add the same Nonce to this script tag so that it can pass the check and not get blocked by the CSP header?
All instances of CspNonceService
share the same instance of RandomNumberGenerator
, which is not thread-safe.
I am seeing a stack trace from your code:
An unhandled exception has occurred while executing the request.
System.Text.Json.JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_SerializerCycleDetected(Int32 maxDepth)
at System.Text.Json.JsonSerializer.Write(Utf8JsonWriter writer, Int32 originalWriterDepth, Int32 flushThreshold, JsonSerializerOptions options, WriteStack& state)
at System.Text.Json.JsonSerializer.WriteAsyncCore(Stream utf8Json, Object value, Type inputType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.SystemTextJsonResultExecutor.ExecuteAsync(ActionContext context, JsonResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|29_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultFilters>g__Awaited|27_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
**at Joonasw.AspNetCore.SecurityHeaders.Csp.CspMiddleware.Invoke(HttpContext context)**
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at SoapCore.SoapEndpointMiddleware.Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
This is new with the switch to .NET Core 3.0
Need to be able to specify require-trusted-types-for
directive:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/require-trusted-types-for
It would be nice to be able to add directives that are not yet supported by the library before building final header result...
When using app.UseStatusCodePagesWithReExecute("/error/{0}")
I get this error whenever I return NotFound()
from any controller.
in /src/Joonasw.AspNetCore.SecurityHeaders/Hsts/HstsMiddleware.cs
on line 25 you need to check if the header has already been added...
if (context.Response.Headers.All(x => x.Key != HeaderName)) context.Response.Headers.Add(HeaderName, _headerValue);
You have the same issue in other places too - everywhere you are adding headers currently.
Hi,
Would you mind adding upgrade-insecure-requests
to the library?
See for more info: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.