2013-01-13 73 views
3

我有方法看起來像該ApiConroller:MVC 4的WebAPI JSON數組劫持

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

它返回一個JSON陣列。我使用jQuery來獲得結果。我該如何防止數組被劫持,如自動操作等?

+0

你是什麼意思* *劫持*?你的JSON究竟會被劫持?你想要保護什麼? –

+0

@DarinDimitrov我認爲他指的是JavaScript數組構造函數漏洞,http://haacked.com/archive/2009/06/24/json-hijacking.aspx – tvanfosson

+0

哦,我明白了。那麼你的回答就直截了當。從我+1。 –

回答

8

您可以在一個通用的方式做到這一點。

添加以下類:

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); 
    } 
} 

而現在,在您的WebApiConfig用這個新替換默認JSonMediaTypeFormatter

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

現在你可以返回任何你想要的IEnumerable,就像你本來沒有,即

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

而且SecureJsonMEdiaTypeFormatter將interc ept它,幷包裝在一個匿名對象,在result屬性:

{ 
    "result": [ 
     { 
      "name": "Toronto Maple Leafs", 
      "league": "NHL" 
     }, 
     { 
      "name": "Montreal Canadiens", 
      "league": "NHL" 
     } 
    ] 
} 
+0

儘管我決定任何服務器端自動安裝都會讓API變得更加晦澀,但我不禁要像你這樣做! – rgripper

+0

或者您可以實施一個xsrf令牌來驗證請求 –

+0

這是一種優雅的方式。 – Julian89757

3

你可以簡單地把你的結果包裝在一個對象中。

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

因爲JavaScript對象是不是一個有效的腳本,這樣可以防止被惡意執行的結果,如哈克解釋在http://haacked.com/archive/2009/06/24/json-hijacking.aspx

+0

我使用過,只是認爲有一種更優雅和自動化的方式來包裝收集每一種方法,而不改變結果類型和增加更多的噪音。 – rgripper