MVC.NET (ASP.NET) Security

A collegae of mine was running some security checks on the site we are building the other day and found some vulnerabilities. Nothing serious, but still: more than I wanted to be in there. So I went searching on the internet for explanations and solutions.

I found out that most of these security issues or vulnerabilities are very easily solvable. The simpler ones I have summarized here, so I and others can find them all together in one article.

Clickjacking

Clickjacking is, to put it simply, that users have been offered something else than they expected with the use of an iframe. With other words within an iframe there are also buttons and links that will propose different behaviour than the user expected (since that iframe obviously lives somewhere else). You can read more on Wikipedia and here and here over at Microsoft.

The solution is quite simple to this vulnerability though. You can simply add the HTTP response header X-FRAME-OPTIONS: DENY to their site's pages to specify that that page should never be displayed in a frame. If you do need iframes (can't imagin why you would want that) it is possible to add the header X-FRAME-OPTIONS: SAMEORIGIN in stead. This specifies that it is allowed to show iframes that match the domain.

In a MVC.NET solution here is how you would solve it. Just add the following to your web.config file:

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <clear />
        <!-- 
            Clickjacking Mitigation
            To help prevent clickjacking on pages that don't need to be framed, the new X-FRAME-OPTIONS header can be included 
            to tell browsers not to allow framing. This only applies to IIS7 within the system.webServer node.
        -->
        <add name="X-FRAME-OPTIONS" value="DENY" />
      </customHeaders>
    </httpProtocol>
  <system.webServer>

Off course this only works in IIS 7 and up, since it uses the system.webServer space. If you want a solution for older browsers check the earlier mentioned article from Microsoft (this one). They explain how you can also archieve this by creating an HTTP module.

Server information headers

IIS gives away all sorts of information about itself and the pages it serves. While this does not really pose a threat it does give away unwanted information and it could give potential hackers clues about how to proceed with their attack on your server and site. So we want to remove all of this information from the headers.

The first piece of information IIS gives away is about itself. In older versions of IIS (5 and 6) you can solve this problem by using a tool created by Microsoft, called UrlScan. in IIS7 this however does not work.The solution here (also works in older IIS versions by the way) is to add a custom header that overrides the one IIS serves. This can be done in your Global.asax or a bit more nicely in a custom HTTP module (one for all your security measures?). The following code should be added (in either):

  public override void Init() 
  {
    this.PreSendRequestHeaders += MvcApplication_PreSendRequestHeaders;
    
    base.Init();
  }
  
  protected void OnPreSendRequestHeaders(object sender, EventArgs e) 
  { 
    // Modify the "Server" HTTP Header
    HttpContext.Current.Response.Headers.Set("Server", "Webserver"); 
  } 

Along with the server information IIS also serves information about the fact it serves ASP.NET. This can be removed very easily from your web.config file. This is how it's done for IIS7:

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <clear />
        <!-- 
            ASP.Net sometimes (depending on the web server) serves an X-Powered-By http header which advertises that the 
            application is ASP.Net (sometimes even if it isn't). This only applies to IIS7 within the system.webServer node.
        -->
        <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>
  <system.webServer>

Along with the server information and the use of ASP.NET IIS also serves information about the ASP.NET version being used. Again this can be removed very easily from your web.config file, just add a single line to the system.web section and your done:

  <system.web>
    <!-- 
        ASP.Net by default serves up the http header X-AspNet-Version with the version information. Again although this 
        doesn't pose a direct risk, it does give more information to potential hackers to let them focus on particular exploits. 
    -->
    <httpRuntime enableVersionHeader="false" />
  </system.web>

And IIS doesn't stop here serving information. It also tells the MVC version used if it is a MVC.NET site. This can also be removed very easily, but not in you web.config file. You have to add the following to your Global.asax Application_Start event.

  protected void Application_Start()
  {
    // ...
    
    // X-AspNetMvc-Version
    // For ASP.Net MVC applications, an additional 'X-AspNetMvc-Version' header is included. 
    // This can be removed by adding the following code to the Application_Start event in the Global.asax file: 
    MvcHandler.DisableMvcResponseHeader = true;
  }

HTTP OPTIONS

Last, but not least we have the HTTP OPTIONS verb. This method represents a request for information about the communication options available. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval. In other words allows users to tell what sort of HTTP options (GET/POST/etc...) are available without actually executing the action.

To turn off the HTTP OPTIONS verb you can simply deny access to unauthorised users. You can do this within the authorization section of the web.config:

  <authorization>
    <deny verbs="OPTIONS" users="*" />
  </authorization>

That's it for now, we have solved a few issues very easily. Most of them no real threats, but it is easy to solve and poses absolutely no issues for the behaviour of your site. So why not fix them along the way.