2009-10-01 14 views
5

Mam aplikację ASP.NET MVC, która jest podobna do kalendarza. Zgodnie z przykładem NerdDinner, aktualizuję wyniki mojej strony edycji za pomocą UpdateMethod()ASP.NET MVC UpdateModel podatny na ataki hakerskie?

W mojej aplikacji niektóre zdarzenia można w pełni dostosować, a niektóre można tylko częściowo dostosować. Mimo że formularz edycji do edytowania częściowo dostosowywalnych zdarzeń ma tylko te pola, to oczywiście ktoś może utworzyć własny formularz z brakującymi danymi i opublikować go w mojej witrynie. Jeśli to zrobią, co powstrzyma kogoś przed zmianą jakichkolwiek/wszystkich pól? Co gorsza, jeśli spróbują zmienić identyfikator (klucz podstawowy)?

Wygląda na to, że UpdateModel() jest podatny na bardzo podstawowe hakowanie. Czy moje obawy są uzasadnione, czy jest coś, czego mi brakuje?

// 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

Tryb łatwy/bezpieczny = twórz modele (nie), a następnie mapuj je do swoich podmiotów za pomocą Automapper. – mxmissile

Odpowiedz

9

Brakuje sekcji dotyczącej "Bezpieczeństwo wiązania modelu". Powinieneś zawsze dołączyć białą listę właściwości, które mogą być aktualizowane przez dowolne metody wprowadzania użytkownika.

Na przykład, od NerdDinner:

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

} 

lub jeśli wywołanie UpdateModel, można utworzyć tablicę ciągów dozwolonych właściwości i zrobić

UpdateModel(myObject, allowedProperties); 

Można zablokować klas sami, aby można było aktualizować tylko niektóre właściwości.

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

Wspaniale, dopóki nie masz 20 lub 30 elementów na ekranie wprowadzania danych, to staje się ból =) –

+2

Możesz także użyć czarnej listy :) – womp

7

Twoje obawy mają rację. Nazywa się to przypisaniem masy. Możesz zabezpieczyć swój kod, zaznaczając swoją klasę jako BindAttribute i ustawiając właściwości Exclude/Include.

1

Istnieją przeciążenia UpdateModel, które pobierają tablicę ciągów nazwanych właściwościami do aktualizacji. Te przeciążenia zaktualizują tylko nazwane właściwości.

Mogą istnieć inne łatwiejsze/bardziej deklaratywne sposoby osiągnięcia tego celu, nie jestem ekspertem w zakresie wiązania danych MVC.

1

Możesz zaznaczyć pola w swoim modelu, które powinny zostać zignorowane przez aktualizację lub przekazać listę pól uwzględnionych/wykluczonych przy użyciu jednego z pozostałych przeciążeń UpdateModel.

4

Możliwe jest, że ktoś przedsiębiorczy/złośliwy zmapuje pola do dowolnej właściwości modelu. Istnieje kilka sposobów obejścia tego problemu: Najprostszym sposobem jest użycie przeciążeń właściwości exclude/include UpdateModel, jak wspomniano wcześniej. Wadą tego jest to, że metoda akceptuje jedynie tablicę ciągów, co może czasem oznaczać, że twój kod nie jest zsynchronizowany, jeśli zmienisz nazwę.

Innym sposobem jest użycie prostego DTO, który przechowuje powiązane pola, możesz wtedy wziąć DTO i zrobić to, co chcesz z obiektem zdarzenia, to oczywiście dodaje inną klasę i jest o wiele bardziej ręczny, ale daje ci o wiele więcej kontrola

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

Innym sposobem może być za pomocą modelu spoiwa klienta dla swojej klasy MyEvent co tylko wiąże żądane pole, choć zapewne przesadą.

Powiązane problemy