Skip to content

Peter-Juhasz/aspnetcoresecurity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ASP.NET Core Security Extensions

dotnet add package PeterJuhasz.AspNetCore.Security.Extensions

Contains a set of high-performance extensions which can help you make your web applications more secure. You can also install each feature invididually as a separate package.

Table of contents

Tag Helpers

  • NoOpener
  • Subresource Integrity
  • Upgrade Insecure Resources

Middlewares

  • Features
    • Redirect Policy
    • Require Authenticated Identity
  • Headers
    • Content Security Policy
    • Expect CT
    • Feature Policy
    • Frame Options
    • HTTP Public Key Pinning
    • Permissions Policy
    • Referrer Policy
    • Report To
    • X-Content-Type-Options
    • X-Download-Options
    • X-Permitted-Cross-Domain-Policies
    • X-Robots-Tag
    • X-UA-Compatible
    • X-XSS-Protection

Features

Content-Security-Policy

Adds the Content-Security-Policy headers to responses with content type text/html.

services.AddContentSecurityPolicy(new CspOptions
{
    DefaultSrc = CspDirective.None,
    StyleSrc = StyleCspDirective.Self,
    ScriptSrc = ScriptCspDirective.Self
        .AddSource(new Uri("https://az416426.vo.msecnd.net/")), // Application Insights
    ImgSrc = CspDirective.Self
        .AddDataScheme(),
    FontSrc = CspDirective.Self,
    ConnectSrc = CspDirective.Empty
        .AddSource(new Uri("https://dc.services.visualstudio.com/")),
});

// ...

app.UseContentSecurityPolicy();

Cross Origin Resource Sharing

Use the built-in support in ASP.NET Core 3.0.

Expect-CT

Adds the Expect-CT header which allows sites to opt in to reporting and/or enforcement of Certificate Transparency requirements.

app.UseExpectCT(enforce: true, maxAge: TimeSpan.FromHours(1));

Feature-Policy (deprecated)

Adds the Feature-Policy header to responses with content type text/html.

app.UseFeaturePolicy(
    new FeatureDirectiveList()
        .Add(FeatureDirective.Payment, "https://payment.example.org/")
        .AddNone(FeatureDirective.Microphone)
        .AddSelf(FeatureDirective.FullScreen)
);

Frame Options (deprecated)

Adds the Frame-Options and X-Frame-Options headers to responses with content type text/html.

app.UseFrameOptions(FrameOptionsPolicy.Deny);

If you want to enable displaying the page in a frame on a particular origin, you can set it like this:

app.UseFrameOptions(new Uri("https://www.example.org"));

HTTP Strict Transport Security

Use the built-in support in ASP.NET Core 3.0.

HTTP Public Key Pinning (deprecated)

Adds the Public-Key-Pinning header to all responses.

app.UseHttpPublicKeyPinning(options => options
    .Pin(fingerprint1, HttpPublicKeyPinningHashAlgorithm.Sha256)
    .Pin(fingerprint2, HttpPublicKeyPinningHashAlgorithm.Sha256)
);

NoOpener

A tag helper that adds the missing noopener link relationship type to your a tags that open in another frame and doesn't reference the same origin.

Add an import for the tag helper (in your _ViewImports.cshtml if you have one):

@addTagHelper *, PeterJuhasz.AspNetCore.Extensions.Security.NoOpener

You don't need any additional changes, the tag helper applies to all links, for example:

<a href="https://example.org/malicious.html" target="_blank">Click here</a>

And adds the missing rel attribute:

<a href="https://example.org/malicious.html" target="_blank" rel="noopener">Click here</a>

Permissions-Policy

Adds the Permissions-Policy header to responses with content type text/html.

app.UsePermissionsPolicy(
    new PermissionsPolicyDirectiveList()
        .Add(PermissionsPolicyPermissions.Payment, "https://payment.example.org/")
        .AddNone(PermissionsPolicyPermissions.Microphone)
        .AddSelf(PermissionsPolicyPermissions.FullScreen)
);

Redirect Policy

Restricts server-side redirects only to trusted origins.

app.UseRedirectPolicy();

You can also specify the trusted origins:

app.UseRedirectPolicy(allowedBaseUris: "https://www.example.org");

Referrer Policy

Adds the Referrer-Policy header to all responses.

app.UseReferrerPolicy(ReferrerPolicy.SameOrigin);

Report-To

Add the Report-To header to all responses.

app.UseReportTo(new ReportingGroup(
    maxAge: TimeSpan.FromDays(30),
    endpoint: "https://example.org/browser-report"
));

Require Authenticated Identity

This is a middleware that you can use to require an authenticated identity on the HttpContext to proceed. For example, you can use this middleware to require authentication for static files.

app.UseWhen(
    context => context.Request.Path.StartsWithSegments("/dist"),
    branch => branch.UseRequireAuthenticatedIdentity()
);

Notes:

  • 401 is returned in case of no authenticated user

Subresource Integrity

A tag helper that computes the integrity attribute for linked styles and scripts from remote origins. It also adds the crossorigin attribute with anonymous value.

Add the required services (in your Startup.cs):

services.AddSubresourceIntegrity();

Add an import for the tag helper (in your _ViewImports.cshtml if you have one):

@addTagHelper *, PeterJuhasz.AspNetCore.Extensions.Security.SubresourceIntegrity

You don't need any additional changes, the tag helper applies to styles and scripts, for example:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

And adds the integrity and crossorigin attributes:

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha256-YLGeXaapI0/5IgZopewRJcFXomhRMlYYjugPLSyNjTY=" crossorigin="anonymous" />
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha256-CjSoeELFOcH0/uxWu6mC/Vlrc1AARqbm/jiiImDGV3s=" crossorigin="anonymous"></script>

Notes:

  • If the integrity attribute is already included, it skips that element and doesn't compute and validate it.
  • In case the remote resource is not available, a warning is logged and the integrity attribute is not included. Page rendering is not interrupted.
  • The hash algorithm used is SHA-256.
  • Hashes are cached in a memory cache indefinitely.

Upgrade Insecure Resources

A tag helper that upgrades insecure links, style, script and image references to HTTPS.

Add an import for the tag helper (in your _ViewImports.cshtml if you have one):

@addTagHelper *, PeterJuhasz.AspNetCore.Extensions.Security.UpgradeInscureResources

You don't need any additional changes, the tag helper applies to all href and src attributes:

<a href="http://example.org/page">Click here</a>
<script src="http://example.org/script.js"></script>

Will be rewritten to:

<a href="https://example.org/page">Click here</a>
<script src="https://example.org/script.js"></script>

X-Content-Type-Options

Adds the X-Content-Type-Options header to all responses.

app.UseXContentTypeOptions(XContentTypeOptions.NoSniff);

X-Download-Options

Adds the X-Download-Options header to each file download.

app.UseXDownloadOptions(XDownloadOptions.NoOpen);

X-Permitted-Cross-Domain-Policies

Adds X-Permitted-Cross-Domain-Policies header to all responses.

app.UseXPermittedCrossDomainPolicies(PermittedCrossDomainPolicy.None);

X-Robots-Tag

Adds the X-Robots-Tag header to all responses.

app.UseXRobotsTag(noIndex: true, noFollow: true);

X-UA-Compatible

Adds the X-UA-Compatible header to each response with text/html media type.

app.UseXUACompatible(InternetExplorerCompatibiltyMode.Edge);

X-XSS-Protection (deprecated)

Adds the X-XSS-Protection header to each response with text/html media type. The default setting enables protection and sets it to block mode.

app.UseXXSSProtection();

Performance

  • All middlewares are strongly typed using the IMiddleware interface
  • All middlewares are singletons, so they don't have to be instantiated for each and every request
  • Response headers are not parsed into objects, low level APIs are satisfactory while providing the same security
  • Header values are pre-rendered, so middlewares are basically allocation free from now (instead of constructing them on the fly, which resulted in lots of new String objects on the heap). Note: this also means that configuration changes won't take effect while running.
  • Breaking change: middlewares must be registered as services before use.

Releases

No releases published

Packages

No packages published

Languages