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-PolicyExpect-CTPublic-Key-PinsReferrer-PolicyStrict-Transport-SecurityX-Content-Type-OptionsX-Frame-OptionsX-Permitted-Cross-Domain-PoliciesX-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/