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/