3

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.?

3
  • What do you mean by hijacking? How exactly your JSON will be hijacked? What are you trying to protect against? Commented Jan 13, 2013 at 17:31
  • @DarinDimitrov I think he's referring to the JavaScript array constructor vulnerability, haacked.com/archive/2009/06/24/json-hijacking.aspx Commented Jan 13, 2013 at 17:41
  • Oh I see. Then your answer is straight to the point. +1 from me. Commented Jan 13, 2013 at 17:43

2 Answers 2

8

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"
        }
    ]
}
Sign up to request clarification or add additional context in comments.

2 Comments

Though I decided that any server side autonesting makes API more obscure, I can't help but like you way of doing it!
alternatively you could just implement an xsrf token to validate requests
3

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

1 Comment

I used that, just thought there is a more elegant and automated way for wrapping collection in every method like that without changing result type and adding more noise.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.