beta-1
This commit is contained in:
21
Readme.md
21
Readme.md
@@ -2,7 +2,7 @@
|
||||
|
||||
<img src="Hat.png" width="350px"/>
|
||||
|
||||
HardHat adds various headers to help protect your site from vulnerablities.
|
||||
HardHat is a set of .net core middleware that adds various headers to help protect your site from vulnerablities. Inspired by [helmetJS](https://helmetjs.github.io). Currently in beta, Content Security Policy, Unit tests, documentation due before 1.0.0. Netherless this should work fine.
|
||||
|
||||
|
||||
In short this allows:
|
||||
@@ -14,11 +14,14 @@ In short this allows:
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
{
|
||||
...
|
||||
app.DnsPrefetch(allow: false); //turn off dns prefetch to keep privacy of users on site
|
||||
app.AddFrameGuard(new FrameGuardOptions(FrameGuardOptions.FrameGuard.SAMEORIGIN)); //prevent content from being loaded in an iframe unless its within the same origin
|
||||
app.UseHsts(maxAge: 5000, includeSubDomains: true, preload: false); //enforce hsts
|
||||
app.AddReferrerPolicy(ReferrerPolicy.NoReferrer);
|
||||
app.AddIENoOpen();
|
||||
app.UseDnsPrefetch(allow: false); //turn off dns prefetch to protect the privacy of users
|
||||
app.UseFrameGuard(new FrameGuardOptions(FrameGuardOptions.FrameGuard.SAMEORIGIN)); //prevent clickjacking, by not allowing your site to be rendered in an iframe
|
||||
// app.UseFrameGuard(new FrameGuardOptions("otherdomain.com")); or allow iframes on another domain
|
||||
app.UseHsts(maxAge: 5000, includeSubDomains: true, preload: false); //tell browsers to always use https for the next 5000 seconds
|
||||
app.UseReferrerPolicy(ReferrerPolicy.NoReferrer); // do not include the referrer header when linking away from your site to protect your users privacy
|
||||
app.UseIENoOpen(); // don't allow old ie to open files in the context of your site
|
||||
app.UseNoMimeSniff(); // prevent MIME sniffing
|
||||
app.UseCrossSiteScriptingFilters(); //add headers to have the browsers auto detect and block some xss attacks
|
||||
...
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
@@ -33,9 +36,3 @@ In short this allows:
|
||||
|
||||
```
|
||||
|
||||
todo:
|
||||
|
||||
* CSP
|
||||
* don't sniff mime type
|
||||
* XSS protection
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HardHat.Example.Controllers
|
||||
{
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace HardHat.Example
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -46,12 +42,15 @@ namespace HardHat.Example
|
||||
{
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
app.DnsPrefetch(allow: false);
|
||||
app.AddFrameGuard(new FrameGuardOptions(FrameGuardOptions.FrameGuard.SAMEORIGIN));
|
||||
app.UseDnsPrefetch(allow: false);
|
||||
app.UseFrameGuard(new FrameGuardOptions(FrameGuardOptions.FrameGuard.SAMEORIGIN));
|
||||
app.UseHsts(maxAge: 5000, includeSubDomains: true, preload: false);
|
||||
app.UseReferrerPolicy(ReferrerPolicy.NoReferrer);
|
||||
app.UseIENoOpen();
|
||||
app.UseNoMimeSniff();
|
||||
app.UseCrossSiteScriptingFilters();
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.AddReferrerPolicy(ReferrerPolicy.NoReferrer);
|
||||
app.AddIENoOpen();
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HardHat
|
||||
namespace HardHat
|
||||
{
|
||||
internal static class Constants
|
||||
{
|
||||
internal const string DnsControlHeader = "X-DNS-Prefetch-Control";
|
||||
internal const string FrameGuardHeader = "X-Frame-Options";
|
||||
internal const string DowloadOptions = "X-Download-Options";
|
||||
internal const string StrictTransportSecurity = "Strict-Transport-Security";
|
||||
internal const string MaxAge = "max-age";
|
||||
internal const string IncludeSubDomains = "; includeSubDomains";
|
||||
internal const string Preload = "; preload";
|
||||
internal const string DowloadOptions = "X-Download-Options";
|
||||
internal const string NoOpen = "noopen";
|
||||
internal const string ReferrerPolicy = "Referrer-Policy";
|
||||
internal const string XContentTypeOptions = "X-Content-Type-Options";
|
||||
internal const string NoSniff = "nosniff";
|
||||
internal const string XXSProtection = "X-XSS-Protection";
|
||||
internal const string OneModeEqualsBlock = "1; mode=block";
|
||||
internal const string Zero = "0";
|
||||
internal const string UserAgent = "User-Agent";
|
||||
|
||||
internal static class Referrers
|
||||
|
||||
internal static class Referrers
|
||||
{
|
||||
internal const string NoReferrer = "no-referrer";
|
||||
internal const string NoReferrerWhenDowngrade = "no-referrer-when-downgrade";
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HardHat
|
||||
|
||||
@@ -4,10 +4,54 @@ namespace Microsoft.AspNetCore.Builder
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static IApplicationBuilder DnsPrefetch(this IApplicationBuilder app, bool allow = false) => app.UseMiddleware<DnsPrefetch>(allow);
|
||||
public static IApplicationBuilder AddFrameGuard(this IApplicationBuilder app, FrameGuardOptions options) => app.UseMiddleware<FrameGuard>(options);
|
||||
/// <summary>
|
||||
/// Browsers can start DNS requests from URLs in your page. This improves performance, but can cause a privacy issue to your users.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="allow"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseDnsPrefetch(this IApplicationBuilder app, bool allow = false) => app.UseMiddleware<DnsPrefetch>(allow);
|
||||
/// <summary>
|
||||
/// The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a frame, iframe, or object . Sites can use this to avoid clickjacking attacks, by ensuring that their content is not embedded into other sites.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="options"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseFrameGuard(this IApplicationBuilder app, FrameGuardOptions options) => app.UseMiddleware<FrameGuard>(options);
|
||||
/// <summary>
|
||||
/// The Strict-Transport-Security HTTP header tells browsers to stick with HTTPS and never visit the insecure HTTP version.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="maxAge">how long the browser should use https in seconds</param>
|
||||
/// <param name="includeSubDomains">include subdomains?</param>
|
||||
/// <param name="preload">is preloaded with google? https://hstspreload.org/ if you don't know then set this to false</param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseHsts(this IApplicationBuilder app, ulong maxAge, bool includeSubDomains = false, bool preload = false) => app.UseMiddleware<Hsts>(maxAge, includeSubDomains, preload);
|
||||
public static IApplicationBuilder AddIENoOpen(this IApplicationBuilder app) => app.UseMiddleware<IENoOpen>();
|
||||
public static IApplicationBuilder AddReferrerPolicy(this IApplicationBuilder app, ReferrerPolicy policy) => app.UseMiddleware<ReferrerPolicyMiddlewear>(policy);
|
||||
/// <summary>
|
||||
/// This middleware sets the X-Download-Options to prevent Internet Explorer from executing downloads in your site’s context.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseIENoOpen(this IApplicationBuilder app) => app.UseMiddleware<IENoOpen>();
|
||||
/// <summary>
|
||||
///A user could upload an image with the .jpg file extension but its contents are actually HTML. Visiting that image could cause the browser to “run” the HTML page, which could contain malicious JavaScript! This is because the MIME type is "sniffed" by the browser
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseNoMimeSniff(this IApplicationBuilder app) => app.UseMiddleware<NoSniff>();
|
||||
/// <summary>
|
||||
/// Typically when users are directed away from your site they have a referrer header. This says where the request is coming from, which has privacy implications for your users.
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="policy">A referrer policy. You can read more about them here: https://www.w3.org/TR/referrer-policy/#referrer-policies </param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseReferrerPolicy(this IApplicationBuilder app, ReferrerPolicy policy) => app.UseMiddleware<ReferrerPolicyMiddlewear>(policy);
|
||||
/// <summary>
|
||||
/// This adds the X-XSS-Protection header which allows the browser to detect and block some xss attacks
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="addOldIE">turning this on for ie8 and 9 can actually cause worse vulnerabilities. By default we do not add old IE, but you can override this behavior</param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseCrossSiteScriptingFilters(this IApplicationBuilder app, bool addOldIE = false) => app.UseMiddleware<XSSProtection>(addOldIE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HardHat
|
||||
{
|
||||
public struct FrameGuardOptions
|
||||
public class FrameGuardOptions
|
||||
{
|
||||
internal readonly string domain;
|
||||
internal readonly FrameGuard? guard;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
20
src/HardHat/NoSniff.cs
Normal file
20
src/HardHat/NoSniff.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace HardHat
|
||||
{
|
||||
public class NoSniff
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
public NoSniff(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public Task Invoke(HttpContext context)
|
||||
{
|
||||
context.Response.Headers[Constants.XContentTypeOptions] = Constants.NoSniff;
|
||||
return _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
|
||||
38
src/HardHat/XSSProtection.cs
Normal file
38
src/HardHat/XSSProtection.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace HardHat
|
||||
{
|
||||
public class XSSProtection
|
||||
{
|
||||
private readonly Regex ieMatch = new Regex(@"(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:)(\d+)", RegexOptions.Compiled);
|
||||
private readonly bool addOldIE;
|
||||
private readonly RequestDelegate _next;
|
||||
public XSSProtection(RequestDelegate next, bool addOldIE = false)
|
||||
{
|
||||
_next = next;
|
||||
this.addOldIE = addOldIE;
|
||||
}
|
||||
|
||||
public Task Invoke(HttpContext context)
|
||||
{
|
||||
var result = Constants.OneModeEqualsBlock;
|
||||
var userAgent = context.Request.Headers[Constants.UserAgent];
|
||||
if(!addOldIE && !string.IsNullOrWhiteSpace(userAgent))
|
||||
{
|
||||
var matches = ieMatch.Match(userAgent);
|
||||
int version;
|
||||
if(matches.Success && int.TryParse(matches?.Groups[2]?.Value, out version) && (version == 7 || version == 8 || version == 9))
|
||||
{
|
||||
result = Constants.Zero;
|
||||
}
|
||||
}
|
||||
context.Response.Headers[Constants.XXSProtection] = result;
|
||||
return _next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.0-beta-1",
|
||||
"description": ".Net core Middleware, Add various headers to help secure your site",
|
||||
"authors": [ "Tommy Parnell" ],
|
||||
"packOptions": {
|
||||
"tags": [ "xss", "clickjack", "clickjacking", "security", ".net core", "Middleware" ],
|
||||
"tags": [ "xss", "clickjack", "clickjacking", "security", ".net core", "Middleware", "core" ],
|
||||
"projectUrl": "https://github.com/tparnell8/TurboLinks.Net",
|
||||
"licenseUrl": "https://opensource.org/licenses/MIT"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user