Tags:
Guest Editor: Today's post is from Taras Kholopkin. Taras is a Solutions Architect at SoftServe, Inc. In this post, Taras will review secure data transmission in the ASP.NET MVC framework.
Secure data transmission is a critical step towards securing our customer information over the web. In fact, many of our SoftServe applications are regulated by HIPAA, which has the following secure data transmission requirements:
- Client-server communication should be performed via secured channel (TLS/HTTPS)
- Client (front-end application) should not pass any PHI data in URL parameters when sending requests to the server
- All data transmission outside of the system should be performed via secure protocol (HTTPS, Direct Protocol, etc.)
To satisfy this requirement, let's examine how to secure data transmission in an ASP.NET MVC application.
Enable HTTPS Debugging
One of my favorite features introduced in Visual Studio 2013 is the ability to debug applications over HTTPS using IIS Express. This eliminates the need to configure IIS, virtual directories, create self signed certificates, etc.
Let's begin by modifying our SecureWebApp from the ASP.NET MVC: Audit Logging blog entry to use HTTPS. First, select the SecureWebApp project file in the Solution Explorer. Then, view the Properties window. Notice we have an option called "SSL Enabled". Flip this to true, and you will see an SSL URL appear:
Now, our SecureWebApp can be accessed at this endpoint: https://localhost:44301/.
RequireHttps Attribute
With HTTPS enabled, we can use the ASP.NET MVC framework to require transport layer encryption for our application. By applying the RequireHttps attribute, our application forces an insecure HTTP request to be redirected to a secure HTTPS connection. This attribute can be applied to an individual action, an entire controller (e.g. AccountController), or across the entire application. In our case, we will apply the RequireHttps attribute globally across the application. To do this, add one line of code to App_Start\FilterConfig.cs:
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); //Apply HTTPS globally filters.Add(new RequireHttpsAttribute()); } }
After applying the require HTTPS filter, the application protects itself from insecure HTTP requests. Notice that browsing to http://localhost:8080/ results in a redirection to a secure https://localhost connection.
Now, it should be noted that the redirect uses the standard HTTPS port number 443. In Visual Studio, you will see a 404 error because the IIS Express instance is using port 44301. Don't be alarmed, on a production system this will work as long as you are hosting your application on the standard HTTPS port 443.
Secure Cookies
Another important step for secure data transmission is protecting authentication cookies from being transmitted insecurely over HTTP. Because our entire site requires HTTPS, start by setting the requireSSL attribute to true on the httpCookies element in the web.config file:
<system.web> <httpcookies httponlycookies="true" requiressl="true" lockitem="true"> </httpcookies>
If you are using ASP.NET Identity, set the CookieSecure option to Always to ensure the secure flag is set on the .AspNet.Application cookie. This line of code can be added to the Startup.Auth.cs file:
app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, CookieHttpOnly = true, CookieSecure = CookieSecureOption.Always, LoginPath = new PathString("/Account/Login"), ... });
If you are using forms authentication, don't forget to set requireSSL to true on the forms element to protect the .ASPXAuth cookie.
<authentication mode="Forms"> <forms loginurl="~/Account/Login" timeout="2880" requiressl="true"> </forms>
After making these changes, login to the application and review the set-cookie headers returned by the application. You should see something similar to this:
HTTP/1.1 200 OK ... Set-Cookie: ASP.NET_SessionId=ztr4e3; path=/; secure; HttpOnly Set-Cookie: .AspNet.ApplicationCookie=usg7rt; path=/; secure; HttpOnly
HTTP Strict Transport Security
Finally, we need to add HTTP Strict Transport Security (HSTS) protection to the application. This protection instructs the browser to always communicate with a domain over HTTPS, even if the user attempts to downgrade the request to HTTP. The HSTS header also happens to prevent HTTP downgrade attack tools, such as sslstrip, from performing man-in-the-middle attacks. More information on this tool can be found in the references below.
With IE finally adding support for the HSTS header in IE11 and Edge 12, all major browsers now support the Strict-Transport-Security header. Once again, one line of code is added to the Global.asax.cs file:
protected void Application_EndRequest() { Response.AddHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains;"); }
The max-age option specifies the number of seconds the browser should upgrade all requests to HTTPS (31536000 seconds = 1 year), and the includeSubDomains option tells the browser to upgrade all sub-domains as well.
Alternatively, you can preload your web site's domain into browser installation packages by registering in the Chrome pre-load list: https://hstspreload.appspot.com/
For more information on security-specific response headers for ASP.NET applications, there is an open source tool that you can use to automatically set the HSTS header. The Security Header Injection Module (SHIM) can be downloaded via NuGet. More information can be found in the link below.
Making these minor configuration and code changes will ensure your data is secure in transit! To learn more about securing your .NET applications, sign up for DEV544: Secure Coding in .NET!
References
- https://shim.codeplex.com/
- http://www.thoughtcrime.org/software/sslstrip/
- http://caniuse.com/#feat=stricttransportsecurity
Taras Kholopkin is a Solutions Architect at SoftServe, and a frequent contributor to the SoftServe United blog. Taras has worked more than nine years in the industry, including extensive experience within the US IT Market. He is responsible for software architectural design and development of Enterprise and SaaS Solutions (including Healthcare Solutions).