2009-10-01 50 views
5

我有一個類似日曆的ASP.NET MVC應用程序。根據NerdDinner示例,我正在使用UpdateMethod()更新我的編輯頁面的結果()ASP.NET MVC UpdateModel容易受到黑客攻擊?

在我的應用程序中,某些事件可完全自定義,某些事件只能部分自定義。儘管編輯部分可自定義事件的編輯表單只有這些可用字段,但顯然有人可以使用缺少的數據創建自己的表單併發布到我的網站。如果他們這樣做,那麼怎樣才能防止某個人改變任何/所有的領域?更糟的是,如果他們試圖改變id(主鍵)呢?

感覺像UpdateModel()容易受到非常基本的黑客攻擊。我的恐懼是否合法,或者是否有我失蹤的東西?

// POST: /MyEvents/Edit/2 
[AcceptVerbs(HttpVerbs.Post), Authorize] 
public ActionResult Edit(int id, FormCollection formValues) 
{ 
    MyEvent myevent = eventRepository.GetMyEvent(id); 

    try 
    { 
     UpdateModel(myevent); 
     eventRepository.Save(); 
     return RedirectToAction("Details", new { id = myevent.MyEventId }); 
    } 
    catch 
    { 
     ModelState.AddRuleViolations(myevent.GetRuleViolations()); 
     return View(new MyEventFormViewModel(myevent)); 
    } 
} 
+0

easy/safe mode =創建form(in)模型,然後通過Automapper將它們映射到您的實體。 – mxmissile 2009-10-01 20:16:19

回答

9

您錯過了「模型綁定安全性」部分。您應該始終包含可以通過任何用戶輸入法更新的屬性白名單。

例如,從NerdDinner範例:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Include="Title, Address")] Dinner dinner) 
{ 

} 

,或者如果你調用的UpdateModel,您可以創建允許屬性的字符串數組,並做

UpdateModel(myObject, allowedProperties); 

您可以鎖定類以便只有某些屬性可以更新。

[Bind(Include="MyProp1,MyProp2,MyProp3")] 
public partial class MyEntity { } 
+0

偉大的,直到你有一個數據輸入屏幕上的20或30個元素,然後它成爲一個痛苦=) – 2009-12-12 06:09:10

+2

你也可以使用黑名單:) – womp 2009-12-12 06:41:46

7

你的擔心是對的。這就是所謂的質量分配。您可以通過BindAttribute和設置Exclude/Include屬性標記您的課程來保護您的代碼。

1

UpdateModel的重載需要更新字符串命名屬性的數組。這些重載只會更新指定的屬性。

可能還有其他更簡單/更具說明性的方法來實現這一點,我不是MVC數據綁定方面的專家。

1

您可以標記模型上應通過更新忽略的字段,或使用其他UpdateModel過載之一傳遞包含/排除字段的列表。

4

對於有進取/惡意的人來說,完全可能將字段映射到模型上的任何屬性。有幾種解決方法

最簡單的方法是使用UpdateModel的exclude/include屬性重載,如前所述。其缺點是該方法只接受一個字符串數組,這有時意味着如果您進行任何重命名,您的代碼將不同步。

另一種方法是使用一個包含綁定字段的簡單DTO,然後您可以採用DTO並按照事件對象執行所需操作,這顯然會增加另一個類並且更加手動,但會爲您提供更多控制

public ActionResult(int id, EditForm form) { 
    MyEvent event = _eventRepository.GetMyEvent(id); 
    event.Name = form.Name; //etc; 
    if (User.IsInRole("Organiser")) { 
     event.Date = form.Date; 
    } 
    return ... 
} 

另一種方式可能是通過你的MyEvent類客戶模型綁定,只有結合你想要的領域,可能是矯枉過正,但。