[ASP.NET MVC] Podmiana id w query stringu

Odpowiedz Nowy wątek
2012-04-02 16:09
0

Witam. Dopiero zaczynam z asp.net mvc i zastanawia mnie jedna rzecz.
Czesto przekazujemy jako parametr jakiegos produktu w id sesji, czy po prostu renderujemy na stronie grupe action linkow, gdzie kazdy bedzie mial w query stringu parametr id produktu.

W jaki sposob zabezpieczyc sie teraz przed nieautoryzowana zmiana id? Skoro wszystko jest jawne, to czy nalezy to recznie szyfrowac? Bo chyba raczej nie trzymac stan w sesji uzytkownika? A moze ponownie sprawdzac czy uzytkownik czy wybrany id, jest z wczesniejszego resulta? Tylko co jesli pobranie takich wiaze sie z duzym czasem przetwarzania?

Chodzi mi o to, jak w najprostrzy sposob automatycznie zabezpieczyc sie przez takimi rzeczami jak prosta podmiana id'ka w linku :)


Senior Full Stack Developer .NET & Angular
edytowany 2x, ostatnio: wasiu, 2012-04-02 16:09

Pozostało 580 znaków

2012-04-02 16:20
Rev
0

Bardzo chciałem zrozumieć o co chodzi, ale nie potrafię. W jaki sposób chcesz przekazać "parametr produktu w id sesji"? O co w ogóle w tym zdaniu chodzi? Dlaczego nie chcesz trzymać stanu w sesji użytkownika? Przecież po to ona jest.


Pozostało 580 znaków

2012-04-02 16:27
ŁF
1

sprawdzaj po stronie serwera, czy dany użytkownik może wykonać akcję na danym obiekcie. nigdy nie polegaj na danych, które przychodzą od klienta.


Pozostało 580 znaków

2012-04-02 19:56
0

@Rev: Trzymanie tego w sesji nie ma sensu, gdyz moga to byc duze ilosci danych, ktore przez 20 minut beda zajmowaly pamiec, a uzytkownik moze zamknac strone w dowolnym momencie.
@ŁF: a jesli sprawdzam to ponownie po stronie serwera i nie trzymam tego w sesji i zajmuje to sporo czasu? Wtedy dzialanie strony jest conajmniej słabe.

W zwyklym ASP.NET'cie np w takim gridzie wykonujac akcje na jakims wierszu, mozna sie pozniej poslugiwac propertisem DataKeys i wydobywac sobie np id czegos co mamy przypisanego do wiersza i bylo to calkiem bezpieczne. Jak zatem podobny stopień bezpieczeństwa uzyskać w MVC, nie zmniejszając wydajności strony czy bezpieczeństwa.

Jedyne co mi przychodzi do głowy to takie witalne rzeczy jak id zaszyfrować (pytanie czy jest jakiś prosty sposób, np atrybut secure, który dane pole z modelu, przy renderowaniu w widoku automatycznie by szyfrował). w SPACJA końcu nie będe trzymał w sesji setek tysięcy rekordów, tylko po to by sprawdzić czy ten przekazany jest poprawny, jak i nie będe kolejnego długiego selecta do tego zapuszczał.


Senior Full Stack Developer .NET & Angular

Pozostało 580 znaków

2012-04-02 20:01
Rev
0

I co, każdemu odwiedzającemu pobierasz setki tysięcy rekordów? Mam wrażenie, że chcesz coś za bardzo przekombinować i znów nie potrafię sobie wyobrazić sytuacji o której mówisz. Spróbuj nakreślić jakiś przykład.


Pozostało 580 znaków

2012-04-02 21:04
j_s_r_n
1
wasiu napisał(a)

Jak zatem podobny stopień bezpieczeństwa uzyskać w MVC, nie zmniejszając wydajności strony czy bezpieczeństwa.

Jedyne co mi przychodzi do głowy to takie witalne rzeczy jak id zaszyfrować (pytanie czy jest jakiś prosty sposób, np atrybut secure, który dane pole z modelu, przy renderowaniu w widoku automatycznie by szyfrował). w SPACJA końcu nie będe trzymał w sesji setek tysięcy rekordów, tylko po to by sprawdzić czy ten przekazany jest poprawny, jak i nie będe kolejnego długiego selecta do tego zapuszczał.

  1. Aplikacje w MVC są z natury bardziej wydajne niż WebForms.
  2. Przekazywanie parametrów(o ile to nie hasła) przez GET/QueryString nie jest niebezpieczne. Niebezpieczne jest to, jak programista z nich korzysta.
  3. Nie wierz w to, co przychodzi z przeglądarki.
  4. Security through obscurity = no security.
  5. Jeżeli w jednej tabeli znajdują się dane do których uprawnienia są per wiersz, to autoryzację i tak powinieneś napisać.
  6. Jeśli select w oparciu o id długo się wykonuje, to masz skopaną strukturę(albo boisz się, że będzie wolno, bo nie wiesz jak wydajne są silniki bazodanowe)
select count(*) 
from products 
inner join users 
     on products.ownerId = users.Id 
where products.id=12 
and users.userName='wasiu'
select count(*) 
from products 
inner join userRoles 
     on products.ownerRoleId=userRoles.roleId 
inner join users 
     on userRoles.userId = users.Id 
where products.id=12 
and users.userName='wasiu' 

jeśli >0 to user ma uprawnienia.
Jak chcesz żeby było trochę szybciej to zaszyj to w stored procedure.

Pozostało 580 znaków

2012-04-02 22:30
0

Panowie, w chwili obecnej sprowadzam to do prostego przykładu, a w praktyce i tak przekłada się to na stored procedury, które mają po kilkadziesiąt/set lini kodu, a nie tam proste selecty z paru tabel. A co do skopanej struktury to często faktycznie bywa, że jest skopona bo ktoś kilkanaście lat temu tak sobie wymyślił i a klient ani myśli o migracji do nowej bazy, czy zmienianiu architektury.

Więc sprowadzając to do prostego przykładu. Mam procedure co zwraca jakiś zakres danych (po filtrowaniach itp) i trwa to powiedzmy 10s, czyli zajebiście długo. Przekazuje wynik do tabeli, a użytkownik w każdym wierszu ma actionlink'a z id wyniku, który po kliknieciu przekazywany jest strony pokazującej dany wynik w szczegółach (np jakiś skomplikowany raport - kolejne 15s).

I w całym poście chodzi o to czy:
a) trzymamy w sesji wyniki kluczy do których użytkownik ma dostęp i przy przejściu do raportu sprawdzamy czy się zgadza.
b) wykonujemy ponownego selecta i tracimy 10s by to sprawdzić (to w ogóle bez sensu ale z tego co zauważyłem często tak jest w entity framework)
c) encryptujemy id'ka i w takiej formie przekazujemy go do widoku wyników, a odkodowujemy w kontrolerze raportu

Lub też coś innego, co by było wspierane automatycznie przez mvc. Czyli jak najprościej i najwydajniej to zrobić. Ot tyle :)
Przepraszam jeśli mój pierwszy post był troche niejasny, dziś zdecydowanie nie jest mój dzień ;)


Senior Full Stack Developer .NET & Angular

Pozostało 580 znaków

2012-04-03 00:21
ŁF
0

Ad a) jeśli rozmiar sesji razy ilość użytkowników ma sensowny rozmiar, to jest to najlepsza, bo najprostsza i skuteczna opcja.
Ad b) użyj cache do zapytań, w zależności od ilości danych na statycznym obiekcie (mało) lub na memcached, velocity itp (dużo).
Ad c) asp-koszmar-programisty-net ma swój zajebisty viewstate, który dzięki dorzuceniu od kilku do - bagatela - kilkuset kB do rozmiaru strony (i do rozmiaru przesyłanych postem i ajaksem danych) chroni integralność danych z nią powiązanych. coś jakby sesja, ale odbijana pomiędzy przeglądarką a serwerem. brzydkie rozwiązanie, ale gotowe, skuteczne i wspierane przez giganta. w takiej sytuacji nic nie potrzebujesz szyfrować, trzymasz sobie wszystkie potrzebne dane w prywatnych zmiennych "instancji" obiektu obsługującego żądania klienta. zresztą co ja tłumaczę, każdy normalny webdeveloper .net zna to rozwiązanie (i brzydzi się go).


Pozostało 580 znaków

2012-04-03 08:38
emfałsi
1
ŁF napisał(a)

Ad c) asp-koszmar-programisty-net ma swój zajebisty viewstate, który dzięki dorzuceniu od kilku do - bagatela - kilkuset kB do rozmiaru strony (i do rozmiaru przesyłanych postem i ajaksem danych) chroni integralność danych z nią powiązanych. coś jakby sesja, ale odbijana pomiędzy przeglądarką a serwerem. brzydkie rozwiązanie, ale gotowe, skuteczne i wspierane przez giganta. w takiej sytuacji nic nie potrzebujesz szyfrować, trzymasz sobie wszystkie potrzebne dane w prywatnych zmiennych "instancji" obiektu obsługującego żądania klienta. zresztą co ja tłumaczę, każdy normalny webdeveloper .net zna to rozwiązanie (i brzydzi się go).

W MVC się tego nie używa ;] Skoro używamy MVC to zazwyczaj bez *.aspx'ów i ViewState'a/PostBack'a.

Pozostało 580 znaków

2012-04-03 08:47
j_s_r_n
0

ad a) Sesja wydaje się ok, pod warunkiem, że ktoś sobie do ulubionych nie wrzuci /Home/12. Wtedy wizyta wygląda tak: przekierowanie na stronę logowania, powrót na stronę /Home/12. W żadnym momencie nie wchodzisz na stronę zawierającą zbiór id do których ma uprawnienia, ergo w sesji nie ma danych względem których można dokonać autoryzacji.
ad b) Nie musisz zwracać całego zbioru wyników, żeby sprawdzić czy zawiera on konkretne id. EF nie jest lekarstwem na całe zło i czasem zwyczajnie trzeba zrobić ExecuteReader/ExecuteScalar. Choćby ze względu na wydajność w przypadku dużych ilości danych(np. raportów). Trzeba dopisać nowe procedury, być może dodać tabele/indeksy/kolumny.
ad c) Nie ma znaczenia, czy link prowadzi do /Home/12, /Home/Zbig12niew, czy /Home/23bjk24h3g4o23ueh23. Jeśli ktoś zdobędzie link to i tak dostanie zbiór danych.

a + c
Jeśli szyfrowanie będzie oparte o zmienną per user w sesji, to nie będzie można przesyłać linków innym, linki będą wygasać(brak ulubionych) i za każdym razem, gdy będziesz musiał wyświetlać dużą liczbę id, konieczne będzie zaszyfrowanie całego zbioru kluczowych/wrażliwych danych(a to też trwa).

Pozostało 580 znaków

2012-04-03 09:21
emfałsi
0
j_s_r_n napisał(a)

ad a) Sesja wydaje się ok, pod warunkiem, że ktoś sobie do ulubionych nie wrzuci /Home/12. Wtedy wizyta wygląda tak: przekierowanie na stronę logowania, powrót na stronę /Home/12. W żadnym momencie nie wchodzisz na stronę zawierającą zbiór id do których ma uprawnienia, ergo w sesji nie ma danych względem których można dokonać autoryzacji.
ad b) Nie musisz zwracać całego zbioru wyników, żeby sprawdzić czy zawiera on konkretne id. EF nie jest lekarstwem na całe zło i czasem zwyczajnie trzeba zrobić ExecuteReader/ExecuteScalar. Choćby ze względu na wydajność w przypadku dużych ilości danych(np. raportów). Trzeba dopisać nowe procedury, być może dodać tabele/indeksy/kolumny.
ad c) Nie ma znaczenia, czy link prowadzi do /Home/12, /Home/Zbig12niew, czy /Home/23bjk24h3g4o23ueh23. Jeśli ktoś zdobędzie link to i tak dostanie zbiór danych.

a + c
Jeśli szyfrowanie będzie oparte o zmienną per user w sesji, to nie będzie można przesyłać linków innym, linki będą wygasać(brak ulubionych) i za każdym razem, gdy będziesz musiał wyświetlać dużą liczbę id, konieczne będzie zaszyfrowanie całego zbioru kluczowych/wrażliwych danych(a to też trwa).

Co Ty bredzisz? Pisałeś kiedykolwiek coś większego w MVC? Bo jakieś dziwne mechanizmy, zwłaszcza w punkcie "a" podsuwasz.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0