Giter Club home page Giter Club logo

aspnetcore-security-headers's People

Contributors

ahouben avatar awarrenlove avatar azure-pipelines[bot] avatar espeng avatar gps-lasrol avatar jcox86 avatar joonaszure avatar juunas11 avatar kant2002 avatar knightpfhor avatar mrmdavidson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aspnetcore-security-headers's Issues

Exclude Hsts middleware for asp.net core 2.2 version

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.

System.Argument Exception when using CSP middleware with UseStatusCodePagesWithReExecute middleware

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:

  • If we add the CSP middleware after UseStatusCodePagesWithReExecute, then the Exception is thrown if the UseStatusCodePagesWithReExecute is invoked (i.e. when a Controller Action uses StatusCode), and is not thrown otherwise.
  • If we add the CSP middleware before 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?

Let application decide when to add CSP http header

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

context.Response.Headers.Add(headerName, headerValue);
where an application may decide whether to add the CSP header or not.

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 ?

Nonce is empty

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?

Add support for checking response type before adding headers

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.

Strict-dynamic support for frames

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?

Alternative syntax

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 ????

Partial view issue

Does asp-add-nonce="true" helper work for partials? In my project it doesn't seem to work.

Add a tag helper to automatically put SHA hash into CSP - alternative to nonce

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.

Usage with a single page application

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?

Adding nonce to a div element with inline style

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?

What about 'data' URIs?

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.

Path in ReportViolationsTo causes 404 when using IIS

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:

  • Areas/Csp/HomeControlller.cs

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 work with Timespan class

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);

Add CspReport Object

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();
}

Access the nonce value

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?

asp.net core 2.1 UseHsts() naming conflict

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)

Add Nonce support for other HTML elements that might have an inline style element

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>

Using Nonces with Blazor

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()

Add Security Headers in Response.OnStarting

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.

Nonce not working in asp.net core mvc

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

Configure CSP in appsettings.json but want to set OnSendingHeader

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.

Appending nonce to scripts added as strings

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?

.NET Core 3.0 Issues

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

ArgumentException: An item with the same key has already been added. Key: Strict-Transport-Security

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.