博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Implementing HTTPS Everywhere in ASP.Net MVC application.
阅读量:6327 次
发布时间:2019-06-22

本文共 9557 字,大约阅读时间需要 31 分钟。

Implementing HTTPS Everywhere in ASP.Net MVC application.

HTTPS everywhere is a common theme of the modern infosys topics. Despite of that when I google for implementation of HTTPS in ASP.Net MVC applications, I find only a handful of horrible questions on StackOverflow, about how to implement HTTPS only on certain pages (i.e. login page). There have been numerous rants about security holes awaiting for you down that path. And !

See that link above? Go and read it! Seriously. I’ll wait.

Have you read it? Troy there explains why you want to have HTTPS Everywhere on your site, not just on a login page. Listen to this guy, he knows what he is talking about.

Problem I faced when I wanted to implement complete “HTTPS Everywhere” in my MVC applications is lack of implementation instructions. I had a rough idea of what I needed to do, and now that I’ve done it a few times on different apps, my process is now ironed-out and I can share that with you here.

1. Redirect to HTTPS

Redirecting to HTTPS schema is pretty simple in modern MVC. All you need to know about is RequireHttpsAttribute. This is named as Attribute and can be used as an attribute on separate MVC controllers and even actions. And I hate it for that – it encourages for bad practices. But luckily this class is also implements IAuthorizationFilter interface, which means this can be used globally on the entire app as a filter.

Problem with this filter – once you add it to your app, you need to configure SSL on your development machine. If you work in team, all dev machines must be configured with SSL. If you allow people to work from home, their home machines must be configured to work with SSL. And configuring SSL on dev machines is a waste of time. Maybe there is a script that can do that automatically, but I could not find one quickly.

Instead of configuring SSL on local IIS, I decided to be a smart-ass and work around it. Quick study of highlighted that the class is not sealed and I can just inherit this class. So I inherited RequireHttpsAttribute and added logic to ignore all local requests:

public class RequreSecureConnectionFilter : RequireHttpsAttribute{    public override void OnAuthorization(AuthorizationContext filterContext)    {        if (filterContext == null)        {            throw new ArgumentNullException("filterContext");        }        if (filterContext.HttpContext.Request.IsLocal)        {            // when connection to the application is local, don't do any HTTPS stuff            return;        }        base.OnAuthorization(filterContext);    }}

If you are lazy enough to follow the link to the source code, I’ll tell you all this attribute does is check if incoming request schema used is https (that is what Request.IsSecureConnection does), if not, redirect all GET request to https. And if request comes that is not secured and not GET, throw exception. I think this is a good-aggressive implementation.

One might argue that I’m creating a security hole by not redirecting to https on local requests. But if an intruder managed to do local requests on your server, you are toast anyway and SSl is not your priority at the moment.

I looked up what filterContext.HttpContext.Request.IsLocal does and how it can have an impact on security. Here is the source code:

public bool IsLocal {        get {            String remoteAddress = UserHostAddress;            // if unknown, assume not local            if (String.IsNullOrEmpty(remoteAddress))                return false;            // check if localhost            if (remoteAddress == "127.0.0.1" || remoteAddress == "::1")                return true;            // compare with local address            if (remoteAddress == LocalAddress)                return true;            return false;        }    }

This is decompiled implementation of System.Web.HttpRequest. UserHostAddress get client’s IP address. If IP is localhost (IPv4 or IPv6), return true. LocalAddress property returns servers IP address. So basically .IsLocal() does what it says on the tin. If request comes from the same IP the application is hosted on, return true. I see no issues here.

By the way, for my implementation of the secure filter. Can’t go without unit testing on this one!

And don’t forget to add this filter to list of your global filters

public static class FilterConfig{    public void RegisterGlobalFilters(GlobalFilterCollection filters)    {        filters.Add(new RequreSecureConnectionFilter());        // other filters to follow...    }}

2. Cookies

If you think that redirecting to https is enough, you are very wrong. You must take care of your cookies. And set all of them by default to be HttpOnly and SslOnly. Read why you need your cookies to be secured.

You can secure your cookies in web.config pretty simple:

The only issue with that is development stage. Again, if you developing locally you won’t be able to login to your application without https running locally. Solution to that is web.config .

So in your web.config you should always have

and in your web.Release.config file add

This secures your cookies when you publish your application. Simples!

Apart from all your cookies to be secure, you need to specifically require authentication cookie to be SslOnly. For that you need to add requireSSL="true" to your authentication/forms part of web.config. Again, this will require you to run your local IIS with https configured. Or you can do web.config transformation only for release. In your web.Release.config file add this into system.web section

4. Strict Transport Security Header

Strict Transport Security Header is http header that tells web-browsers only to use HTTPS when dealing with your web-application. This reduces the risks of . To add this header by default to your application you can add add this section to your web.config:

Again, the same issue as before, developers will have to have SSL configured on their local machines. Or you can do that via web.config transformation. Add the following code to your web.Release.config:

5. Secure your WebApi

WebApi is very cool and default template for MVC application now comes with WebApi activated. Redirecting all MVC requests to HTTPS does not redirect WebApi requests. So even if you secured your MVC pipeline, your WebApi requests are still available via HTTP.

Unfortunately redirecting WebApi requests to HTTPS is not as simple as it is with MVC. There is no [RequireHttps]available, so you’ll have to make one yourself. Or copy the code below:

using System;using System.Net;using System.Net.Http;using System.Threading;using System.Threading.Tasks;using System.Web;public class EnforceHttpsHandler : DelegatingHandler{    protected override Task
SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // if request is local, just serve it without https object httpContextBaseObject; if (request.Properties.TryGetValue("MS_HttpContext", out httpContextBaseObject)) { var httpContextBase = httpContextBaseObject as HttpContextBase; if (httpContextBase != null && httpContextBase.Request.IsLocal) { return base.SendAsync(request, cancellationToken); } } // if request is remote, enforce https if (request.RequestUri.Scheme != Uri.UriSchemeHttps) { return Task
.Factory.StartNew( () => { var response = new HttpResponseMessage(HttpStatusCode.Forbidden) { Content = new StringContent("HTTPS Required") }; return response; }); } return base.SendAsync(request, cancellationToken); }}

This is a global handler that rejects all non https requests to WebApi. I did not do any redirection (not sure this term is applicable to WebApi) because there is no excuse for clients to use HTTP first.

WARNING This approach couples WebApi to System.Web libraries and you won’t be able to use this code in self-hosed WebApi applications. But there is a . I have not used it because have been written before I learned about better way. And I’m too lazy to fix this -)

Don’t forget to add this handler as a global:

namespace MyApp.Web.App_Start{    public static class WebApiConfig    {        public static void Register(HttpConfiguration config)        {            // other configurations...            // make all web-api requests to be sent over https            config.MessageHandlers.Add(new EnforceHttpsHandler());        }    }}

6. Set up automatic security scanner for your site

is a great tool that checks for a basic security issues on your application. The best feature is scheduled scan. I’ve set all my applications to be scanned on weekly basis and if something fails, it emails me. So far this helped me once, when error pages on one of the apps were messed up. If not for this automated scan, the issue could have stayed there forever. So go and sign-up!

Conclusion

This is no way a complete guide on securing your application. But this will help you with one of the few steps you need to take to lock down your application.

you can copy my web.Release.config transformation file, in case you got confused with my explanation.

转载地址:http://mrgaa.baihongyu.com/

你可能感兴趣的文章
Qt之文本编辑器(二)
查看>>
python编译时检查语法错误
查看>>
考题纠错2
查看>>
SQL——索引
查看>>
Python新手快速入门教程-基础语法
查看>>
JVM性能调优入门
查看>>
关于raid的基本原理、软raid的实现演示
查看>>
科技企业的幕后推手,人工智能究竟有何魔力
查看>>
详解Oracle临时表的几种用法及意义
查看>>
HTML(七)------ 表格
查看>>
如何成为一个设计师和程序员混合型人才
查看>>
unable to load selinux policy. machine is in enforcing
查看>>
2015年10月23日作业
查看>>
MySQL5.7 加强了root用户登录安全性
查看>>
CentOS 6.3_Nagios安装配置与登录
查看>>
加强型的记录集权限(数据集权限、约束表达式设置功能)实现方法界面参考...
查看>>
Linux 内存机制
查看>>
linux下定时任务
查看>>
SharePoint 2013 部署 Part 1
查看>>
DWGSee看图纸dwg文件阅读器免费下载地址
查看>>