Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC 4 WebAPI json array hijacking

I have ApiConroller with method looking like that:

[HttpGet]
public IEnumerable<MyValue> Values()
{
     return db.MyValues.ToList();
}

It returns a JSON array. I use jQuery to get results. How do I keep that array from being hijacked, smth like autonesting, etc.?

like image 901
rgripper Avatar asked Sep 21 '26 23:09

rgripper


2 Answers

You can do it in a generic way.

Add the following class:

public class SecureJsonMediaTypeFormatter : JsonMediaTypeFormatter
{
    public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext)
    {
        if ((typeof (IEnumerable).IsAssignableFrom(type)))
        {
            value = new {result = value};
        }
        return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
    }
}

And now, in your WebApiConfig replace the default JSonMediaTypeFormatter with this new one:

    config.Formatters.RemoveAt(0);
    config.Formatters.Insert(0, new SecureJsonMediaTypeFormatter());

Now you can return any IEnumerable you wish, like you originally did, i.e.

[HttpGet]
public IEnumerable<MyValue> Values()
{
     return db.MyValues.ToList();
}

And the SecureJsonMEdiaTypeFormatter will intercept it, and wrap in an anonymous object, under result property:

{
    "result": [
        {
            "name": "Toronto Maple Leafs",
            "league": "NHL"
        },
        {
            "name": "Montreal Canadiens",
            "league": "NHL"
        }
    ]
}
like image 173
Filip W Avatar answered Sep 26 '26 08:09

Filip W


You could simply wrap your result in an object.

   return new { values = db.MyValues.ToList() };

Because a JavaScript object isn't a valid script, this prevents the result from being executed maliciously, as Haack explains at http://haacked.com/archive/2009/06/24/json-hijacking.aspx

like image 27
tvanfosson Avatar answered Sep 26 '26 06:09

tvanfosson