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.
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
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();
Use the built-in support in ASP.NET Core 3.0.
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));
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)
);
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"));
Use the built-in support in ASP.NET Core 3.0.
Adds the Public-Key-Pinning
header to all responses.
app.UseHttpPublicKeyPinning(options => options
.Pin(fingerprint1, HttpPublicKeyPinningHashAlgorithm.Sha256)
.Pin(fingerprint2, HttpPublicKeyPinningHashAlgorithm.Sha256)
);
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>
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)
);
Restricts server-side redirects only to trusted origins.
app.UseRedirectPolicy();
You can also specify the trusted origins:
app.UseRedirectPolicy(allowedBaseUris: "https://www.example.org");
Adds the Referrer-Policy
header to all responses.
app.UseReferrerPolicy(ReferrerPolicy.SameOrigin);
Add the Report-To
header to all responses.
app.UseReportTo(new ReportingGroup(
maxAge: TimeSpan.FromDays(30),
endpoint: "https://example.org/browser-report"
));
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
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.
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>
Adds the X-Content-Type-Options
header to all responses.
app.UseXContentTypeOptions(XContentTypeOptions.NoSniff);
Adds the X-Download-Options
header to each file download.
app.UseXDownloadOptions(XDownloadOptions.NoOpen);
Adds X-Permitted-Cross-Domain-Policies
header to all responses.
app.UseXPermittedCrossDomainPolicies(PermittedCrossDomainPolicy.None);
Adds the X-Robots-Tag
header to all responses.
app.UseXRobotsTag(noIndex: true, noFollow: true);
Adds the X-UA-Compatible
header to each response with text/html
media type.
app.UseXUACompatible(InternetExplorerCompatibiltyMode.Edge);
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();
- 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.