Tuesday, April 22, 2014

AppSensor and MVC: Unexpected HTTP Commands

So, I have decided to try and implement the some of the OWASP AppSensor controls inside an MVC project.  I will go into details about the end goal of this project in another post, but for now I am going to talk about the Unexpected HTTP Commands detection point.

This is a first stab.  Currently the only response is to log the request in the logs.

In MVC, the current set of http method controls are implemented as ActionMethodSelectorAttribute.  What this means is that you apply the control on a method by method basis.  This approach will probably be good when implementing other controls, but for this one, we need something more global.

This article has a really good explanation of action filters and how to use them.  The filter itself is quite simple, since all we are doing is comparing the reported http verb to a list of expected ones.



        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (!Enabled)
            {
                return;
            }

            var httpMethod = filterContext.HttpContext.Request.GetHttpMethodOverride();

            if (
                acceptedVerbs.Any(
                    x =>
                        x.Equals(httpMethod,
                            StringComparison.InvariantCultureIgnoreCase)))
            {
                return;
            }

            httpMethod = SanitizeHttpMethod(httpMethod);

            Logger.LogRequestException(filterContext.HttpContext.Request.Url.AbsolutePath,
                SecurityConstants.UnexpectedHttpCommands,
                httpMethod,
                filterContext.HttpContext.Request.UserHostAddress);

            filterContext.Result = new HttpNotFoundResult();
        }

A couple of notes.

1)  filterContext.HttpContext.Request.GetHttpMethodOverride() returns the http method as listed in the request.  Remember that this is untrusted code and should be sanitized before writing to the logs.

2)  Verbs can actually be restricted earlier in the pipeline.  Firstly, you can use Request Filtering to limit the accepted verbs.  This method works, but doesn't allow the application to handle the request and thus limit our ability to build in the response mechanisms.  Secondly, in the handler definition you can define the list of verbs to respond.  If you try to use a verb that isn't on this list, you will get an HTTP 405 error.  Both these mechanism are great (and log to the IIS logs) but they don't allow our application to handle and keep track of violations.  To bypass the handler definition, you can use * in the accepted verbs list.

The code is located in github