2010-05-11 8 views
8

Hii,Jak chronić się przed naruszeniem ciągu zapytania?

Mam ciąg kwerendy typu "http://project/page1.aspx?userID=5". Operacja nie zostanie wykonana, jeśli parametr "ID użytkownika" został zmieniony ręcznie. Jak to jest możliwe?

+1

Wystarczy rodzaju wyjaśnienia - Zgaduję w scenariuszu już podawane na stronę; ktoś kliknął przycisk gdzieś indziej i trafił na stronę "http: //project/page1.aspx? userID = 5". A teraz na tej stronie wpiszą pewne wartości i nie chcesz, aby zamieniły to 5 w pasku adresu na 7, wciśnij "zapisz" i uruchom swoją witrynę aktualizując informacje o użytkowniku 7, poprawny? – Tom

Odpowiedz

3

hii wszystkim, dziękuję za pomoc ... i mam pewne rozwiązanie różnicowe z innych stron. nie wiem, że to najlepsze rozwiązanie. to jest kodowanie wartości za pomocą algorytmu szyfrowania i deszyfrowania ... Przykładowy kod został napisany w ten sposób ...

<a href='Page1.aspx?UserID=<%= HttpUtility.UrlEncode(TamperProofStringEncode("5","F44fggjj")) %>'> 
     Click Here</a> <!--Created one anchor tag and call the function for TamperProofStringEncode--> 


    
private string TamperProofStringEncode(string value, string key) 
{ 
      System.Security.Cryptography.MACTripleDES mac3des = new System.Security.Cryptography.MACTripleDES(); 
      System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
      mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key)); 
      return Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(value)) + "-" + Convert.ToBase64String(mac3des.ComputeHash(System.Text.Encoding.UTF8.GetBytes(value))); 
     } 
 

w obciążeniu stronie 'Strona1' nazywamy algorytm dekodowania do dekodowania ciąg kwerendy

try 
     { 
      string DataString = TamperProofStringDecode(Request.QueryString["UserID"], "F44fggjj"); 
      Response.Write(DataString); 
     } 
     catch (Exception ex) 
     { 
      Response.Write(ex.Message); 
     } 

private string TamperProofStringDecode(string value, string key) 
    { 
     string dataValue = ""; 
     string calcHash = ""; 
     string storedHash = ""; 

     System.Security.Cryptography.MACTripleDES mac3des = new System.Security.Cryptography.MACTripleDES(); 
     System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
     mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key)); 

     try 
     { 
      dataValue = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(value.Split('-')[0])); 
      storedHash = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(value.Split('-')[1])); 
      calcHash = System.Text.Encoding.UTF8.GetString(mac3des.ComputeHash(System.Text.Encoding.UTF8.GetBytes(dataValue))); 

      if (storedHash != calcHash) 
      { 
       //'Data was corrupted 
       throw new ArgumentException("Hash value does not match"); 
       // 'This error is immediately caught below 

      } 
     } 
     catch (Exception ex) 
     { 
      throw new ArgumentException("Invalid TamperProofString"); 
     } 

     return dataValue; 

    } 
+0

Nadal uważam, że możesz uciec z korzystania z sesji. Ale jeśli z jakiegoś powodu rajd absolutnie ** potrzebujesz **, aby zrobić to za pomocą ciągu zapytania i jesteś gotów pójść tą ścieżką, to prawdopodobnie będzie działać w ten sposób. Wciąż miałbym jednak paskudny zapach w moich ustach. Wciąż zależy ... ** Dlaczego ** chcesz to lub ** co dokładnie ** chcesz osiągnąć? Być może jesteś na niewłaściwym torze ... – scherand

+0

Moim użyciem jest, wysłałem wiadomość z zawartością linku wraz z identyfikatorem użytkownika. Kiedy kliknę link w mailu przejdę na stronę, strona wyświetli szczegóły konkretnego użytkownika –

1

Nie można stwierdzić, czy została zmieniona ręcznie. Jeśli używasz ciągów zapytań, to musisz się upewnić, że nie ma znaczenia, czy zostanie zmieniony. na przykład jeśli używasz go do pokazania użytkownikowi jego danych konta, musisz sprawdzić, kto jest wybranym użytkownikiem, jest bieżącym użytkownikiem i wyświetlać komunikat o błędzie zamiast danych użytkownika, jeśli tak nie jest.

+1

Chcę tylko dodać: ASP.NET ma sesję, przechowywać informacje o tym, kto jest tam zalogowany i sprawdzić kod, jeśli zalogowany użytkownik może zobaczyć dane. – Felix

+0

Oczywiście. Zaszyfruj lub zaszyfruj ciąg zapytania przy użyciu współdzielonego tajnego klucza, włącz tę zakodowaną lub zaszyfrowaną wartość w ciągu zapytania, a następnie przelicz ją i sprawdź, czy pasuje przed użyciem ciągu zapytania. – xr280xr

3

To brzmi jak dziwne wymaganie. Czy próbujesz wdrożyć jakieś rodzime zabezpieczenia? Jeśli tak, naprawdę nie powinieneś.

W każdym razie jednym ze sposobów, w jaki można to zrobić, byłoby pobranie całego adresu URL http://project/page1.aspx?userID=5 i obliczenie jego md5 sum. Następnie dodajesz sumę md5 do końcowego adresu URL, na przykład http://project/page1.aspx?userID=5&checksum=YOURCALCULATEDMD5SUM. Następnie w page1.aspx musisz sprawdzić, czy parametr checksum jest poprawny.

Jednak takie podejście jest dość naiwne i nie musiałoby długo czekać, aby ktokolwiek mógł znaleźć algorytm, którego używałeś. Gdyby tak było, mogliby "łatwo" zmienić identyfikator użytkownika i obliczyć sumę md5. Bardziej niezawodnym rozwiązaniem byłoby takie, w którym suma kontrolna została zaszyfrowana za pomocą klucza, do którego tylko Ty miałeś dostęp. Ale znowu muszę zakwestionować twój motyw, aby to zrobić, ponieważ istnieją inne rozwiązania bezpieczeństwa, które są znacznie lepsze.

+0

Czy nie byłoby to strasznie blisko tego, co sesja (token) robi "za darmo" w ASP.NET? Daje to użytkownikowi mniej lub bardziej losowy/bez znaczenia Id (identyfikator sesji/token), który jest następnie używany do identyfikacji odpowiednich danych (sesji). Czy się mylę? – scherand

+1

@scherand: Sortuj ... W twoim przypadku rzeczywiste dane będą przechowywane po stronie serwera, podczas gdy w tym przypadku dane (ID użytkownika = 5) są przechowywane w adresie URL. Może być oznaczony zakładką, nie spowoduje problemów, jeśli masz wiele stron otwieranych w tym samym czasie, itp. –

+0

... co wskazuje na dobry punkt. Jeśli użytkownicy uzyskują dostęp do tego adresu URL, nie ma możliwości późniejszego usunięcia tego dostępu bez wdrożenia mechanizmu logowania/uprawnień lub zmiany algorytmu sumy kontrolnej. –

0

Cóż - to zależy :)

Jedną z możliwości jest umieszczenie userID do zmiennej sesji. Użytkownik nie może zobaczyć ani edytować wartości.

Jeśli masz inne środki w celu wykrycia, czy wartość jest nieważny (czyli nie istnieje lub nie może być dla tego użytkownika (który można zidentyfikować poprzez jakiś inny sposób) lub tym podobne) można uciec z walidacji wpisz się za kod.

Jednak, jak zapewne wiesz, nie możesz uniemożliwić użytkownikowi zmiany ciągu zapytania.

3

Nie możesz.

Wszystko w żądaniu HTTP (w tym adres URL, ciąg zapytania, pliki cookie, ...) znajduje się pod kontrolą klienta i jest łatwe do sfałszowania.

Dlatego ważne jest, aby umieścić na białej liście prawidłowe treści, ponieważ klient może dowolnie dodawać wszystko, co mu się podoba, oprócz tego, co chcesz otrzymać.

+5

Myślę, że OP zdaje sobie sprawę, że (s) nie może ** uniemożliwić ** użytkownikowi zmiany ciągu zapytania. Ale - do pewnego stopnia - (s) może być w stanie ** chronić ** aplikację przed zmienionym łańcuchem zapytań. I o tym właśnie myślę chodzi. Tylko moje dwa pensy. – scherand

1

Jeśli użytkownik może zmienić rekord 5, ale na przykład nie może zarejestrować 7, należy to wymusić po stronie serwera. Aby to zrobić, musisz być w stanie zidentyfikować użytkownika, wymagając loginu i dając mu unikalny klucz sesji, który jest przechowywany w ciasteczku przeglądarki lub jako inny parametr w ciągu zapytania adresu URL.

Istnieją liczne pakunki/moduły/biblioteki w językach człowieka do czynienia z uwierzytelniania i sesji w rozsądny sposób - rolka jesteś właścicielem na własne ryzyko :)

Powiązane problemy