h bob h bob - 3 months ago 33
ASP.NET (C#) Question

How do I stop leaking implementation details in my Azure Mobile app's OData errors?

I'm using Azure Mobile App Service.

Suppose I have a

Customer
entity, with an
Orders
navigation property. Then I can do this:

http://foo.url.com/tables/Customer?$expand=Orders


But suppose I try to expand a non-navigation property
Foo
:

http://foo.url.com/tables/Customer?$expand=Foo


Then I'll get this on the client (or Postman):

{
"message": "The query specified in the URI is not valid. Property 'Foo' on type 'my.namespace.Customer' is not a navigation property. Only navigation properties can be expanded.",
"exceptionMessage": "Property 'Foo' on type 'my.namespace.Customer' is not a navigation property. Only navigation properties can be expanded.",
"exceptionType": "Microsoft.Data.OData.ODataException",
"stackTrace": " at Microsoft.Data.OData.Query.SyntacticAst.ExpandBinder... VERY LONG STACKTRACE..."
}


Or suppose I try to expand non-existent property
Bar
:

http://foo.url.com/tables/Customer?$expand=Bar


Then I'll get this on the client (or Postman):

{
"message": "The query specified in the URI is not valid. Could not find a property named 'Bar' on type 'my.namespace.Customer'.",
"exceptionMessage": "Could not find a property named 'Bar' on type 'my.namespace.Customer'.",
"exceptionType": "Microsoft.Data.OData.ODataException",
"stackTrace": " at Microsoft.Data.OData.Query.SyntacticAst.ExpandBinder... VERY LONG STACKTRACE"
}


If I edit the config to include
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never
then it still leaks the namespace in this error (also it encourages the attacker to perform an enumeration attack and try all kinds of permutations):

{
"message": "The query specified in the URI is not valid. Property 'Foo' on type 'my.namespace.Customer' is not a navigation property. Only navigation properties can be expanded."
}


and

{
"message": "The query specified in the URI is not valid. Could not find a property named 'Bar' on type 'my.namespace.Customer'."
}


This leaks lots of implementation details which are interesting to an attacker. How do I suppress/replace that error message?

Answer

(answer updated with new info)

It turns out that this happens with Web API by itself, and the standard ExceptionFilter and ExceptionHandler mechanisms don't seem to work.

One thing that does seem to work for rewriting the response if you get a 400 is the following:

public class MyExceptionFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Response.StatusCode == System.Net.HttpStatusCode.BadRequest)
        {
            actionExecutedContext.Response.Content = new StringContent("An error occurred.");
        }
    }
}

There's probably a better way than this.