A set of Asp.Net Core middlewares for adding security headers to ASP.NET Core web apps.
The library allows you to add the following HTTP security headers:
Content-Security-Policy
Expect-CT
Public-Key-Pins
Referrer-Policy
Strict-Transport-Security
X-Content-Type-Options
X-Frame-Options
X-Permitted-Cross-Domain-Policies
X-XSS-Protection
Visual Studio Package Manager Console:
Install-Package MarkoPapic.AspNetCoreSecurityHeaders -Version 0.1.0
dotnet CLI:
dotnet add package MarkoPapic.AspNetCoreSecurityHeaders --version 0.1.0
You can add security headers by adding middlewares to your Asp.Net Core pipeline:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseXssProtection();
//other middlewares
}
You can add the Content-Security-Policy
header using the UseCsp
extension method:
app.UseCsp(x => {
x.DefaultSources.AllowSelf();
x.ScriptSources.AllowSelf().AllowHosts("https://example1.com", "https://example2.com");
x.StyleSources.AllowHash("sha256", "Q0E0NTUyMzFGRTJFRUYyNkM1Mjg4ODJBREE0ODNDQTY2Mzc2OTYzQ0U2OUZDNEE5RjMyMDI0NzlGQjExNTgwMg==");
x.FrameAncestors.AllowNone();
x.PluginTypes.AllowMimeType("application/x-java-applet");
x.AddReportingGroup(rg => {
rg.Group = "examplegroup";
rg.Endpoints.Add(new ReportGroupEndpoint("https://reportserver.com/report"));
rg.IncludeSubdomains = true;
});
});
The above example would result in the following HTTP headers being added to the HTTP response:
Content-Security-Policy: connect-src `self` https://example1.com https://example2.com; style-src sha256-Q0E0NTUyMzFGRTJFRUYyNkM1Mjg4ODJBREE0ODNDQTY2Mzc2OTYzQ0U2OUZDNEE5RjMyMDI0NzlGQjExNTgwMg==; plugin-types application/x-java-applet; frame-ancestors 'none'; report-to examplegroup
Report-To: {"group":"examplegroup","max_age":0,"include_subdomains":true,"endpoints":[{"url":"https://reportserver.com/report","priority":0,"weight":0}]}
You can set up the connect-src
directive of the Content-Security-Policy
header using the ConnectSources
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.ConnectSources.AllowSelf().AllowHosts("https://example1.com", "https://example2.com");
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowSelf() |
Adds self to the directive value. |
AllowAny() |
Adds * to the directive value. |
AllowHosts(params string[] hosts) |
Adds host/s to the directive value. |
AllowSchemas(params string[] schemas) |
Adds schema/s to the directive value. |
AllowUnsafeInline() |
Adds unsafe-inline to the directive value. |
AllowUnsafeEval() |
Adds unsafe-eval to the directive value. |
AllowNonce(ICspNonceService nonceService) |
Adds the nonce (for specific inline scripts) to the directive value. You should provide the implementation of the ICspNonceService interface, that will be used to generate the nonce. |
AllowHash(string item) |
Adds the hash of the script or style to the directive value. |
AllowHash(string algorithm, string hashedSource) |
Adds the hash of the script or style to the directive value. |
WithStrictDynamic() |
Adds the strict-dynamic to the directive value. |
ReportSample() |
Adds the report-sample to the directive value. |
You can set up the default-src
directive of the Content-Security-Policy
header using the DefaultSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the font-src
directive of the Content-Security-Policy
header using the FontSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the frame-src
directive of the Content-Security-Policy
header using the FrameSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the img-src
directive of the Content-Security-Policy
header using the ImgSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the manifest-src
directive of the Content-Security-Policy
header using the ManifestSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the media-src
directive of the Content-Security-Policy
header using the MediaSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the object-src
directive of the Content-Security-Policy
header using the ObjectSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the prefetch-src
directive of the Content-Security-Policy
header using the PrefetchSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the script-src
directive of the Content-Security-Policy
header using the ScriptSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the style-src
directive of the Content-Security-Policy
header using the StyleSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the webrtc-src
directive of the Content-Security-Policy
header using the WebRtcSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the worker-src
directive of the Content-Security-Policy
header using the WorkerSources
property of the CspOptionsBuilder
. The setup is the same as for connect-src
directive (and any other fetch directive).
You can set up the base-uri
directive of the Content-Security-Policy
header using the BaseUri
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.BaseUri.AllowSelf().AllowHosts("https://example1.com", "https://example2.com");
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowSelf() |
Adds self to the directive value. |
AllowAny() |
Adds * to the directive value. |
AllowHosts(params string[] hosts) |
Adds host/s to the directive value. |
AllowSchemas(params string[] schemas) |
Adds schema/s to the directive value. |
AllowUnsafeInline() |
Adds unsafe-inline to the directive value. |
AllowUnsafeEval() |
Adds unsafe-eval to the directive value. |
AllowNonce(ICspNonceService nonceService) |
Adds the nonce (for specific inline scripts) to the directive value. You should provide the implementation of the ICspNonceService interface, that will be used to generate the nonce. |
AllowHash(string item) |
Adds the hash of the script or style to the directive value. |
AllowHash(string algorithm, string hashedSource) |
Adds the hash of the script or style to the directive value. |
WithStrictDynamic() |
Adds the strict-dynamic to the directive value. |
ReportSample() |
Adds the report-sample to the directive value. |
You can set up the plugin-types
directive of the Content-Security-Policy
header using the PluginTypes
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.PluginTypes.AllowMimeType("application/x-java-applet");
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowAny() |
Sets the directive value to * . |
AllowMimeType(string mimeType) |
Adds the specified MIME type to the directive value. |
You can set up the sandbox
directive of the Content-Security-Policy
header using the Sandbox
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.Sandbox.AllowPopups();
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowAny() |
Sets the directive value to * . |
AllowForms() |
Adds allow-forms to the directive value. |
AllowModals() |
Adds allow-modals to the directive value. |
AllowOrientationLock() |
Adds allow-orientation-lock to the directive value. |
AllowPointerLock() |
Adds allow-pointer-lock to the directive value. |
AllowPopups() |
Adds allow-popups to the directive value. |
AllowPopupsToEscapeSandbox() |
Adds allow-popups-to-escape-sandbox to the directive value. |
AllowPresentation() |
Adds allow-presentation to the directive value. |
AllowSameOrigin() |
Adds allow-same-origin to the directive value. |
AllowScripts() |
Adds allow-scripts to the directive value. |
AllowTopNavigation() |
Adds allow-top-navigation to the directive value. |
You can set up the form-action
directive of the Content-Security-Policy
header using the FormAction
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.FormAction.AllowSelf().AllowHosts("https://example1.com", "https://example2.com");
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowSelf() |
Adds self to the directive value. |
AllowAny() |
Adds * to the directive value. |
AllowHosts(params string[] hosts) |
Adds host/s to the directive value. |
AllowSchemas(params string[] schemas) |
Adds schema/s to the directive value. |
AllowUnsafeInline() |
Adds unsafe-inline to the directive value. |
AllowUnsafeEval() |
Adds unsafe-eval to the directive value. |
AllowNonce(ICspNonceService nonceService) |
Adds the nonce (for specific inline scripts) to the directive value. You should provide the implementation of the ICspNonceService interface, that will be used to generate the nonce. |
AllowHash(string item) |
Adds the hash of the script or style to the directive value. |
AllowHash(string algorithm, string hashedSource) |
Adds the hash of the script or style to the directive value. |
WithStrictDynamic() |
Adds the strict-dynamic to the directive value. |
ReportSample() |
Adds the report-sample to the directive value. |
You can set up the frame-ancestor
directive of the Content-Security-Policy
header using the FrameAncestors
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.FrameAncestors.AllowSelf().AllowHosts("https://example1.com", "https://example2.com");
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
AllowNone() |
Sets the directive value to none . |
AllowSelf() |
Adds self to the directive value. |
AllowAny() |
Adds * to the directive value. |
AllowHosts(params string[] hosts) |
Adds host/s to the directive value. |
AllowSchemas(params string[] schemas) |
Adds schema/s to the directive value. |
You can set up the block-all-mixed-content
directive of the Content-Security-Policy
header by calling the BlockAllMixedContent()
method of the CspOptionsBuilder
:
app.UseCsp(x => {
x.BlockAllMixedContent();
});
This method will add the block-all-mixed-content
directive to the Content-Security-Policy
header.
You can add the require-sri-for
directive to the Content-Security-Policy
header using the RequireSriFor
property of the CspOptionsBuilder
:
app.UseCsp(x => {
x.RequireSriFor.Script();
});
You can use the following methods to set up the directive:
Method | Description |
---|---|
Script() |
Sets the directive value to script . |
Style() |
Sets the directive value to style . |
ScriptStyle() |
Sets the directive value to script style . |
You can add the upgrade-insecure-requests
directive to the 'Content-Security-Policy' header by calling the UpgradeInsecureRequests()
method of the CspOptionsBuilder
:
app.UseCsp(x => {
x.UpgradeInsecureRequests();
});
This method will add the upgrade-insecure-requests
directive to the Content-Security-Policy
header.
You can add the reporting group for your Content Security Policy by calling the AddReportingGroup(Action<ReportGroupOptions> optionsAction)
method of the CspOptionsBuilder
:
app.UseCsp(x => {
// ...
x.AddReportingGroup(rg => {
rg.Group = "examplegroup";
rg.Endpoints.Add(new ReportGroupEndpoint("https://reportserver.com/report"));
rg.IncludeSubdomains = true;
});
});
This will add the appropriate report-to
directive to the Content-Security-Policy
header, as well as the Report-To
header.
You can add the Expect-CT
header using the UseExpectCt
extension method:
app.UseExpectCt(x => x.SetMaxAge(TimeSpan.FromDays(1)).Enforce());
The above example would result in the following HTTP header being added to the HTTP response:
Expect-CT: enforce, max-age=86400
You can set the max-age
directive to the 'Expect-CT' header by calling the SetMaxAge(TimeSpan maxAge)
method of the ExpectCtOptionsBuilder
:
app.UseExpectCt(x => x.SetMaxAge(TimeSpan.FromDays(2)));
The default value for the max-age
directive is 1 day.
You can add the enforce
directive to the 'Expect-CT' header by calling the Enforce()
method of the ExpectCtOptionsBuilder
:
app.UseExpectCt(x => x.Enforce());
You can add the report-uri
directive to the 'Expect-CT' header by calling the SetReportUri(string reportUri)
method of the ExpectCtOptionsBuilder
:
app.UseExpectCt(x => x.SetReportUri("https://reportserver.com/uri"));
You can add the Public-Key-Pins
header using the UseExpectCt
extension method:
app.UseHpkp(x => x.AddPins("VGhpcyBpcyBzb21lIFN1YmplY3QgUHVibGljIEtleSBJbmZvcm1hdGlvbiBmaW5nZXJwcmludC4=", "QW5kIGFub3RoZXIgU3ViamVjdCBQdWJsaWMgS2V5IEluZm9ybWF0aW9uIGZpbmdlcnByaW50Lg==")
.SetMaxAge(TimeSpan.FromHours(3))
.IncludeSubdomains());
The above example would result in the following HTTP header being added to the HTTP response:
Public-Key-Pins: pin-sha256="VGhpcyBpcyBzb21lIFN1YmplY3QgUHVibGljIEtleSBJbmZvcm1hdGlvbiBmaW5nZXJwcmludC4="; pin-sha256="QW5kIGFub3RoZXIgU3ViamVjdCBQdWJsaWMgS2V5IEluZm9ybWF0aW9uIGZpbmdlcnByaW50Lg=="; max-age=10800; includeSubDomains
You can add pins to the Public-Key-Pins
header by calling the AddPins(params string[] pins)
method of the HpkpOptionsBuilder
:
app.UseHpkp(x => x.AddPins("VGhpcyBpcyBzb21lIFN1YmplY3QgUHVibGljIEtleSBJbmZvcm1hdGlvbiBmaW5nZXJwcmludC4="));
You can set the max-age
directive to the Public-Key-Pins
header by calling the SetMaxAge(TimeSpan maxAge)
method of the HpkpOptionsBuilder
:
app.UseHpkp(x => x.AddPins("VGhpcyBpcyBzb21lIFN1YmplY3QgUHVibGljIEtleSBJbmZvcm1hdGlvbiBmaW5nZXJwcmludC4=", "QW5kIGFub3RoZXIgU3ViamVjdCBQdWJsaWMgS2V5IEluZm9ybWF0aW9uIGZpbmdlcnByaW50Lg==")
.SetMaxAge(TimeSpan.FromHours(3)));
The default value for the max-age
directive is 5 hours.
You can add the includeSubDomains
directive to the Public-Key-Pins
header by calling the IncludeSubdomains()
method of the HpkpOptionsBuilder
:
app.UseHpkp(x => x.AddPins("VGhpcyBpcyBzb21lIFN1YmplY3QgUHVibGljIEtleSBJbmZvcm1hdGlvbiBmaW5nZXJwcmludC4=", "QW5kIGFub3RoZXIgU3ViamVjdCBQdWJsaWMgS2V5IEluZm9ybWF0aW9uIGZpbmdlcnByaW50Lg==")
.IncludeSubdomains());
You can add the reporting group for your Public Key Pinning Extension by calling the AddReportingGroup(Action<ReportGroupOptions> optionsAction)
method of the HpkpOptionsBuilder
:
app.UseHpkp(x => {
// ...
x.AddReportingGroup(rg => {
rg.Group = "examplegroup";
rg.Endpoints.Add(new ReportGroupEndpoint("https://reportserver.com/report"));
rg.IncludeSubdomains = true;
});
});
This will add the appropriate report-to
directive to the Public-Key-Pins
header, as well as the Report-To
header.
You can add the Referrer-Policy
header using the UseReferrerPolicy
extension method:
app.UseReferrerPolicy(ReferrerPolicyOptions.SameOrigin);
The above example would result in the following HTTP header being added to the HTTP response:
Referrer-Policy: same-origin
The ReferrerPolicyOptions
enum supports the following values:
Value | Description |
---|---|
NoReferrerWhenDowngrade |
Sets the directive value to no-referrer-when-downgrade . |
NoReferrer |
Sets the directive value to no-referrer . |
Origin |
Sets the directive value to origin . |
OriginWhenCrossOrigin |
Sets the directive value to origin-when-cross-origin . |
SameOrigin |
Sets the directive value to same-origin . |
StrictOrigin |
Sets the directive value to strict-origin . |
StrictOriginWhenCrossOrigin |
Sets the directive value to strict-origin-when-cross-origin . |
UnsafeUrl |
Sets the directive value to unsafe-url . |
You can add the Strict-Transport-Security
header using the UseHsts
extension method:
app.UseHsts();
The above example would result in the following HTTP header being added to the HTTP response:
Strict-Transport-Security: max-age=2592000
You can set the max-age
directive to the Strict-Transport-Security
header by setting the MaxAge
property of the HstsOptions
:
app.UseHsts(x => { x.MaxAge = TimeSpan.FromDays(20); });
The default value for the max-age
directive is 30 days.
You can add the includeSubDomains
directive to the Strict-Transport-Security
header by setting the IncludeSubDomains
property of the HstsOptions
:
app.UseHsts(x => { x.IncludeSubDomains = true; });
You can add the preload
directive to the Strict-Transport-Security
header by setting the Preload
property of the HstsOptions
:
app.UseHsts(x => { x.Preload = true; });
Documentation in progress.
Documentation in progress.
Documentation in progress.
Documentation in progress.
git clone https://github.com/MarkoPapic/AspNetCoreSecurityHeaders.git
cd AspNetCoreSecurityHeaders
dotnet restore
dotnet build ./MarkoPapic.AspNetCoreSecurityHeaders.sln
dotnet test ./MarkoPapic.AspNetCoreSecurityHeaders.UnitTests/