Zobaczmy na prosty przykład obrazujący opisany powyżej problem:
Model:
Code:
Na podstawie modelu tworzymy widok edycji danych użytkownika:
Code:
Pole SecreetField zostało za komentowane (nie pojawi się w źródłach wygenerowanego dokumentu).
W kontrolerze wprowadzamy prosty kod który uaktualni obiekt użytkownika na podstawie przekazanych przez Binding wartości:
Code:
Rozwiązanie można powiedzieć książkowe - poza jednym szczegółem - brakuje SaveChanges na obiekcie Context, którego akurat w tym przypadku nie mam (nie korzystam z bazy danych a ze statycznej kolekcji).
Wydawałoby się że powyższy przykład jest poprawny. Jednak jest jedna rzecz którą przeoczyliśmy podczas tworzenia tego rozwiązania - nasi użytkownicy. Zobaczmy co mogłoby się stać, gdyby ktoś chciał wykorzystać aplikację w sposób który nie chcemy:
Przepraszam za słabą jakość, ale chodzi tutaj o samo sedno problemu. Mianowicie jeżeli użytkownik będzie chciał zaatakować naszą stroną i w naszym modelu znajdzie się pole typu IsAdmin, użytkownik może przesłać ten parametr bezpośrednio do mechanizmu bindowania (np. tak jak ja za pomocą QueryString).
W jaki sposób możemy zapobiec takiemu zachowaniu? Otóż istnieje kilka rozwiązań:
1. Stworzenie osobnych modeli do edycji, wyświetlania
2. Skorzystanie z atrybutu Bind:
Code:
Kolejne pola, które nie mają brać udziału w bindowaniu wymieniamy po przecinku. Możemy oczywiście także wskazać, które pola mają brać udział w bindowaniu.
3. Metoda UpdateModel jako jeden z argumentów przyjmuje tablicę pól, które mają zostać uaktualnione:
Code:
4. Kolejną możliwością jest stworzenie np. interfejsu:
Code:
następnie w metodzie UpdateModel podajemy ten model:
Code:
5. Jeszcze jedną możliwością, jest nałożenie atrybuty ReadOnly na dane pole w modelu:
Code:
Mechanizm bindowania respektuje tak nałoży atrybut na dane pole.
Brak komentarzy:
Prześlij komentarz