Securing your HTML Form in ASP.NET MVC

By now, developers should really understand how to build a form and properly secure it.  But this still seems to allude some.  It’s rather embarrassing to fail security assessments for certain secuirty flaws that can be easily avoided.

In this blog, a refresher on the basics will be covered for securing your post as well as writing an extension to add to your MVC Infrastrucutre to be used by all of your team members.

It does not cover data validation.  I am really focusing on the form and the action of that form.  In addition, this is also from the perspective of a business web application that is only accessed via an authenticated user.

Let’s get started…

Poorly Secured Form and Action

Let’s take a simple Edit many developers write everyday and show the numerous flaws with this.  Here is the Razor View:

<h2>Edit</h2>
@using (Html.BeginForm())
{
     ...  Something here with a submit button...
}

Then the controller action would look something similar to this:

public ActionResult Edit(YourModel yourModel)
{
     if (ModelState.IsValid)
     {
          SaveYourModel(yourModel);
          return RedirectToAction("Index");
     }
     return View(client);
}

There are numerous concerns with the above form.

  1. When changing sensitive data, it should only happen via the proper HTTP Action.  So setup your ActionMethodSelectorAttributes properly.
  2. What about Cross-Site Request Forgery?  The above easily allows a hacker to submit data so prevent that as best as possible.
  3. Check the referrer.  Make sure the referrer is your site.
  4. Who is the originator?  Usually, this is the site that served the form.  So check the refferer.
  5. Next, who can change this data.  If only authenticated users, then which ones?

Crash course on ActionMethodSelectorAttribute

What is an ActionMethodSelectorAttribute?  It is an attribute on your controller’s action that is used to influence the selection of an action method.  This is easy to see the benefit of using them.

You can control the routing in MVC to actions decorated with HTTPGet.

[HttpGet()]
public ActionResult Edit(int id)
{
     YourModel yourModel = GetYourModel(id)
     return View(yourModel);
}

Or control the routing for inserting, updating and deleting of data using HTTPPost.

[HttpPost()]
public ActionResult Edit(YourModel yourModel)
{
     if (ModelState.IsValid)
     {
          SaveYourModel(yourModel);
          return RedirectToAction("Index");
     }
     return View(client);
}

When a user navigates to the Edit page for from a link, double clicking a row in a grid, or by any other means, that action should be called via a HTTPGet; therefore the first Action is called due to the HTTPGet attribute on that method.  Once on that page, the user then modifies the data and clicks a submit button in a form performing a POST thus calling the second Action decorated with HTTPPost.

For a complete list of action methods, click the following link for ActionMethodSelectorAttributes.

When do you want to use an ActionMethodSelectorAttribute?  In my opinion, pretty much on every Action in your controller.

Rules to live by:

1.  If you are selecting data to display in your Action method, then your Action should be decorated with the HTTPGet Attribute.

2.  If you are creating, updating or deleting data via your Action method, then your Action should be decorated with the HTTPPost Attribute.

Oh, and by the way, using HTTPPost helps prevent some attacks via CSRF (see next section).  Without that ActionMethodSelectorAttribute, it’s easy for a hacker to create links that a user can click and unknowingly modify their data.  

Without the HTTPPost a well crafted link (obviously depending on your model and your action etc…) can be used to update sensitive info.  Even worse, if your id is just an identity column in SQL Server and if you did not properly secure your form, a hacker could call this link over and over again for each identity id in your database, thus updating your data to what ever he wants.

http://localhost:2572/InsecureDOR/EditSubmit?ClientId=3&FirstName=Maverick&MiddleInitial=A&LastName=Smith

Pretty scary if your site really contains sensitive information like account information, employee data or critical business processes that if disrupted by a hacker causes serious damage to your company’s reputation.

So use HTTPPost and you will prevent the above hacks via get from working.

Cross-Site Request Forgery (CSRF)

Cross-Site Request Forgery (CSRF) is the #8 security flaw on the OWASP Top 10 for 2013. Follow the link for great information about CSRF.  For nitty grittey detail, read “Part 5: Cross-Site Request Forgery (CSRF), 1 Nov 2010 in Troy Hunt’s OWASP Top 10 book. It’s free. This will explain in great detail how an attacker can take advantage of your site. Luckily for us, we don’t have to implement the “Synchronizer Token Pattern” as Tony explains. Instead, we just need to add the following in our form:

@Html.AntiForgeryToken()

Then on the Controller’s Action, the following ActionFilter must be added.

[HttpPost()]
[ValidateAntiForgeryToken()]
public ActionResult Edit(YourModel yourModel)

This handles most CSRF attacks.

Note:  The user must accept cookies.  This only works with POST Requests.  It does not work with GET Requests.

Without a valideAntiForgeryToken, the server will threw exceptions like the following:

AntiForgeryException

AntiForgeryExceptionMissing

Can this be circumvented?  Why, yes….  But, a hacker has to actually get the AntiForgeryToken, then craft a POST using the correct form values.  Gettign the AntiForgeryToken is possible if your site  is vulnerable to XSS or your users are on older browser’s that allow cross-domain access.  Therefore, dropping support for older browsers in web applications is critical when the data is sensitve.  But that might be easier said than done.

The next step is to check the referrer.

Checking the Referrer

The next issue that I see with the above code is that the post could originate from another site.   There are expections, but for most business web application, a post originates from your site.

In order to check the referrer, you need to write a Attribute that inherits from AuthorizeAttribute:

public class IsPostedFromThisSiteAttribute : AuthorizeAttribute
{
  public override void OnAuthorization(AuthorizationContext filterContext)  {
    if (filterContext.HttpContext != null)
    {
      if (filterContext.HttpContext.Request.UrlReferrer == null)
        throw new System.Web.HttpException("IsPostedFromThisSite has invalid post - Missing UrlReferrer!"); 
       if (filterContext.HttpContext.Request.UrlReferrer.Host != filterContext.HttpContext.Request.Url.Host)
          throw new System.Web.HttpException("IsPostedFromThisSite has invalid post - Form was not submitted from this site!");
    }
    base.OnAuthorization(filterContext);
 }
}

Now, use this Attribute on your posts by applying it to the Action:

 [AcceptVerbs(HttpVerbs.Post)]
 [IsPostedFromThisSite]
 public ActionResult MyAction()

Checking the Origin

See the Origin on the following site:

https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet

Authenticated or Authorized

Next check the user to see if the user is authenticated and authorized to perform the action.

Finally

Build an HTML Extension to make this even easier to follow in your Business Application.  It is so easy to do…

Conclusion

These techniques help tremendously when securing your site, protecting your data and for passing security assessments.  So don’t forget to use them in all your forms and protect your reputation, your companies reputation and your bottom line.

More coming soon…

Security Assessment 101: Failed because of my cookies???

What really?  My security assessment failed because of my cookies.  But I only use a couple of cookies to store certain user preferences.  Those cookies are there only for user convince.  Guess what?  That third-party that ran the security assessment doesn’t care.  All they care about is that you have cookies and that you are not securing your cookies properly.

You can easily pass your security assessment by opening Web.Config and setting the http Only setting to true and also turning on SSL for your cookies (assuming you only have SSL);

<httpCookies httpOnlyCookies=”true” requireSSL=”true” />

But you do need to understand the ramifications of these settings.

If your JavaScript is accessing your cookies then setting httpOnlyCookies to true will break your code.  HttpOnly cookies help mitigate XSS and prevents cookies from being accessed vias client-side scripting.  Therefore, depending on how your code is implemented may mean you have some refactoring to do.

Finally, my sites normally run using SSL only.  Therefore, I set requireSSL to true.  This only allows the cookie to be sent back over a connection using SSL/TLS.  This is especially important with the Session Id cookie.  You certainly do not want that to be passed over HTTP since that could be stolen and used to hack your site.

 

 

 

 

Security Assessment 101: Failed due to Login Enumeration

Wait a second?  Really, I can’t tell my user that they locked out the account.  Yep!!!  For sites containing highly sensitive information like employee information, financial information, etc…  you will fail a security assessment because you are telling a hacker the account is locked out.

Why is that?

The concern is a hacker attempted to login with an account many times.  The hacker gets the “The account is locked out due to 5 failed attempts”.  Now the hacker knows he has a good account name.  One more piece of information that can help that hacker figure out how to get in.  Once the hacker gets a good user name, he can keep trying to hack the account each time it is reset.  Or, he might just use a little social engineering and call your help desk.  Using the URL and account name, the hacker might be able to convince your help desk to change the password without even verifying other information on the account.  Then the hacker has a good account with a good password.  Now your hacked but don’t even know it until it is way too late.  It could be weeks before the real user tries to login and figures out he can’t and then calls the help desk.  By then the hacker could have downloaded anything that user has access to, created another user account, etc…

It is best to avoid showing messages like these to the user:

  • The password is invalid.
  • The account is locked out.

Best Practice

Always show the same response for a failed login:

  • The username and password is invalid.  Please try again.

When a user calls the help desk for a password reset:

  • The help desk must verify information about the user.
  • The help desk should be able to see past history and be able to ask the user when they successfully logged in last time.
  • The help desk should be able to see as much information about any failed login attempts like IP Address, number of failed attempts, etc…  If the failed attempts are out of China but your users are only in a few locations in the United States, well you might have a problem…
  • The help desk should reset the password and send a password reset email to the email account on file.

So solving this problem is not just about coding a secure login page but also letting your help desk understand social engineering and hacking.

 

Security Assessment 101: Skip HTTP and just use HTTPS

So you built this awesome business web app.  You sold it to your customer and it’s now in production.  You’re using SSL which is even configured for best practices.  See my previous post on securing SSL.  But what happens when a user goes to your web application.  It probably redirects them to HTTPS so the user can login over SSL.

Why do that???

That is the question to ask yourself.  Why redirect users from HTTP to HTTPS to login.  Why not ALWAYS use SSL???  I really do not believe you need HTTP or Port 80 turned on at all for business web applications.  Here are my assumptions with Business Web Application:

  • Most interactions with your site is behind the login page.  By most, I really mean like 99%.
  • The data is sensitive, company proprietary, etc…
  • You have employee information, financial information, etc…

So in this scenario, there is no real reason to have HTTP bindings setup in IIS for your site.  Turn port 80 off on the firewall and only allow Port 443.  Don’t even give the hacker a chance to see the traffic over HTTP or an avenue to hack your server over port 80.

But what about the customer???

They won’t know to use HTTPS…  For me this is pretty easy answer.  When sending the welcome package to your customer, explain to them why you did this and tell them the URL is only accessible over HTTPS.  I have been doing this for years and yes we have had a few calls to the help desk.  But VERY, VERY few calls.

 

Security Assessment 101: What gives? My SSL failed?!?

You delivered your awesome business application and it’s running in production.  You are a developer and have some limited System Admin skills so obviously your company decided you were the perfect person to set up your production environments.  The data is sensitive so obviously you have SSL turned on.  Everyone involved is in ecstatic!!!  Then out of the blue, your customer calls to schedule a security assessment.  First thought might be “I have SSL so that should be fine, but I’m nervous about my login page, XSS, CSRF, SQL Injection, etc.”  News flash:  SSL has vulnerabilities!!!  And it is very easy for third-parties to identify those issues with your site during a security assessment.  But even better, it is VERY easy for you to determine that your site has vulnerabilities so take the time to test your site (even if you are not the system admin) and fix it before your site goes live.

Due diligence/Disclaimer

This is to provide you guidance.  You must do your own due diligence and validation by testing first in a non-production environment.  Also, changing Cipher security in Windows Server may disable RDP so be very careful!!!  

This article is written based on Windows Server 2008 R2.  I have not tested with Windows Server 2012 but am fairly certain it should apply.

See my disclaimer.

Operating System

Which OS are you using in production?  I highly recommend having at least Windows Server 2008 R2.  If you only have Windows Server 2008 you will not be able to fix several items with your SSL.  You will probably need to start a migration plan.

Resources

The following resources are invaluable:

In addition, here are resources to help understand and fix items:

In addition, you need to understand the browsers you support.  That is rather easy for my specific scenario.  I only support IE.  My biggest problem has been getting users off of older versions of IE.  Here are a couple great links to read up on:

How concerned should you be about SSL

Well that is for you to decide based on your content and it’s sensitivity…  I believe anything that requires an account (username and password), bank information, credit card information, personal information, … then you should be very concerned and take this seriously.

If you want to be scared to death about using free WiFi at your local coffee shop or at the airport, then check out Troy Hunt’s site and read his articles about the “Pineapple“.  That concerns me the most due to some of the sensitive info my applications have.

Start by testing your site:

This is very easy to do.  Navigate to the following url:  https://www.ssllabs.com/.  Then click “Test your server” which will take you to a page like this:

Obviously, you do now want to see this:

Failed SSL

Failed SSL

Once your review your grade, there are additional details to review.  Normally, my certificate is not an issue.  So let’s jump ahead to the next section that is rather important:  “Protocols”.

Failed Protocols

Failed Protocols

Notice that TLS 1.2 and 1.1 are not turned on; however, modern browsers support them so it is important to have them turned on.  SSL 2.0 is not secure and has not been so for years; therefore, this protocol needs to be turned off.  In addition, I turn off SSL 3.0 too.  The next section to reviews is the Cipher Suites:

Failed Ciphers

Failed Ciphers

This order is not good.  It is the default out of the box for Windows Server 2008 R2.  It is so easy to fix.  More to come on that later.  Next, you should review  the “Handshake Simulation”.  I only support IE so I only review those.  You may support many browsers.  You want the browser to support Forward Secrecy which is denoted with FS.  You can see that none of the handshake simulation supports FS and some even support RC4 which is an issue too due to vulnerabilities discovered last year.

Failed Handshake

Failed Handshake

Next, is to review the Protocol Details.  This provides great information including links to read and review.

Failed Protocol Details

Failed Protocol Details

Before Fixing your server

You must be very careful.  If you turn off all of the RC4 protocols you may disable RDP.  See the following article:

In addition, your users may have TLS turned off by default or due to company policy.  They will need to turn it on in IE under the Advanced tab for Internet Options; otherwise they will not be able to connect to your site.

IE Internet Options Advanced

IE Internet Options Advanced

How to fix your SSL

Luckily, fixing your SSL issues is very easy for Window Server 2008 R2.  First start by downloading IISCrypto.exe from Nartac.

After downloading, I ran my virus scanner against the file just to make sure there is nothing suspicious.  You never know if that site was hacked.  If you are wary about using this executable, you could write your own by following the Microsoft Support article.

*****  TEST IN A UAT OR QA SITE FIRST!!!   *****

Follow these instructions for configuring SSL on your Windows 2008 R2 Server:

  1. Take any backup precautions as you see fit.  You will be changing the registry.
  2. Run IISCrypto.exe
  3. Click the configure Best Practices button.  Turn off SSL 3.0.
  4. Click Apply.
  5. The tool marks some registry keys incorrectly according to the Microsoft Support article.  It uses 0x99999999 which may be fine but I update them anyway to reflect the values in the support article.
  6. Click Start, click Run, type regedit, and then click OK.
  7. In Registry Editor, locate the following registry key/folder:  HKey_Local_Machine\System\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0
  8. Ensure that the DisabledByDefault  key shows 0x00000000 (0) under the Data column (it should by default). If it doesn’t, right-click and select Modify and enter 0 as the Value data.
  9. Repeat step 8 for SSL 3.o.   If you want SSL 3.0 turned off, then make sure the “Enabled” value is 0x00000000 (0); otherwise, it should be 1.
  10. Then repeat for  TLS 1.0, 1.1, and 1.2 making sure “Enabled” is set to 1.
  11. Restart the computer.
  12. Re-validate your SSL using SSLLabs.com, ServerSniff.net or the Public SSL Server Database

Results using SSL Labs

Now that the server has been properly configured, you should see these results:

Passed SSL

Passed SSL

Now you can see that my production site only support TLS 1.0, 1.1 and 1.2.  I have turned off SSL 2.0 and SSL 3.0.

Passed Protocols

Passed Protocols

Next, check the Cipher Suites:

Passed Cipher Suites

Passed Cipher Suites

Notice the order that the Ciphers are in.  Note:  I keep the RC4 Cipher.  From what I understand this is necessary for RDP.  There may be a way to configure RDP to use a different Cipher but until I have time to figure that out, I am keeping this Cipher.

In addition, notice how the FS (Forward Secrecy) ciphers are at the top.

Next, check out the handshake:

Passed Handshake

Passed Handshake

Remember, I am only concerned about IE 7 and above.  We will be dropping support for IE 7 soon and IE 8 on XP.  The rest of the handshakes for IE are using FS which is great!  You may need to support multiple browsers so you will need to test accordingly.

Finally, check out the Protocol Details.

Passed Protocol Details

Passed Protocol Details

Conclusion

I hope this article helps those of you with limited System Admin skills.  It took me a while to figure all of this out since my main occupation is Software Architect/Sr Developer…   I am definitely not a System Admin but as a developer I do understand the importance of secure coding as well as following best practices on my production environments.

Getting started with writing secure ASP.NET MVC Code

Over the last few years, I have become very focused on writing secure code.  One of the main driving forces for this is the number of security assessments my application has undergone over the last few years as well as the plethora of information now easily accessible.  So where does one start with writing secure code?  More than likely you already have already started.  But this is a question every developer needs to ask themselves and figure out how to keep up with the latest and greatest.

OWASP

Unless you have been living under a rock for the past decade, then you should already know who OWASP is.  But since some still don’t know, OWASP stands for “Open Web Application Security Project”.

https://www.owasp.org

Note:   you cannot access the OWASP website over HTTP.  First lesson about securing your web applications.  Use HTTPS all the time!

Every year OWASP puts out a Top 10 list.

https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

Troy Hunt

Troy Hunt is awesome! Who is he? Quoting from his web site, Troy Hunt is a “Software Architect and Microsoft MVP”. He writes about security concepts and process improvements for software delivery.

Visit his site (www.troyhunt.com) and follow him on Twitter

I stumbled upon his book in early 2012. I am still amazed at how much information is in this book and the time and dedication he put into it. His book covers the Top 10 OWASP Issues for ASP.NET Web Applications. This awesome book is located here:

http://www.troyhunt.com/2011/12/free-ebook-owasp-top-10-for-net.html

Read it! It is a quick read and will enlighten you to so many topics on security. The book was written for ASP.NET Web Forms; however, it can easily be adopted to ASP.NET MVC. Some of my future topics will cover this.

If you are a member of Pluralsight, you can watch his videos at:

http://pluralsight.com/training/Courses/TableOfContents/owasp-top10-aspdotnet-application-security-risks

Fiddler 2

I love Telerik! Almost as much as my wife and kids. That said, I was nervous when they took over Fiddler. Not anymore. It is still free and they continue to improve it. What is important about Fiddler? Well if you read Troy Hunt’s book or watched his video, then you know how easy it is to test aspects of your application and security using Fiddler. For those of you who do not know about Fiddler, it is a free web debugging proxy which logs all HTTP traffic between your local machine and web application. You can use it to debug traffic on a PC, Max or Linux. You can check cookies, headers and cache directives. You can use it to tamper with client requests and server responses to see how your application is working. Plus many more great features…

You can find fiddler at http://fiddler2.com/.

Code Analysis in Visual Studio

Use it!!! All the time. Make it part of your process when checking in your code. It is very simple to do. The hardest part is making it a solid, consistent habit!

Use SSL

If you have a web application, use SSL. But unfortunately it is not that easy. You also have to make sure your server is configured properly. There HTTPS protocols that are not secure and allow “Man in the middle” attach or can easily be decrypted. To avoid that, you have to configure your server properly and keep up with the latest. Hard to do when you are a developer and should be something your system admins in production handle for you. More on this topic in a later blog…

Great Resources:

https://www.ssllabs.com/

Conclusion

Hope this info is helpful.   More security article to follow very soon!!!