Implementacja bezpiecznych, unikalnych" jednorazowych " adresów URL aktywacji w ASP.NET (C#)

Mam scenariusz, w którym użytkownicy strony, którą buduję, potrzebują możliwości wprowadzania podstawowych informacji do formularza internetowego bez konieczności logowania. Strona jest rozwijana z ASP.NET/C# i używa MSSQL 2005 do swoich danych relacyjnych.

Użytkownicy zostaną wysłani e-mailem z witryny, podając im unikalny link do wprowadzenia konkretnych informacji, które są wymagane. E-mail będzie bardzo podobny do stylu e-mail, który wszyscy otrzymujemy podczas rejestracji na stronach takich jak fora, zawiera losowo generowany, unikalny parametr URL odnoszący się do jednego celu (np. Weryfikacja adresu e-mail dla forum).

Moje zapytania dotyczą bezpiecznej implementacji tego problemu. Rozważałem użycie GUID jako unikalnego identyfikatora, ale nie jestem pewien jego konsekwencji w świecie bezpieczeństwa.

  1. czy GUID jest wystarczająco długi, aby wartości nie mogły być łatwo odgadnięte (lub wymuszone w czasie)?
  2. Is. net ' s GUID implementacja wystarczająco przypadkowa w tym sensie, że istnieje jednakowa szansa na wygenerowanie wszystkich możliwych wartości w"przestrzeni kluczowej"?

  3. Jeśli użycie identyfikatora GUID jest akceptowalnym podejściem, czy witryna powinna przekierować do informacji poprzez przepisanie adresu URL lub skojarzenie informacji w datatable z identyfikatorem GUID jako odnośnikiem?

  4. Czy przepisanie adresu URL ukryje prawdziwe źródło danych?

  5. Czy powinienem rozważyć użycie TSQL SELECT nevid() jako Generator GUID nad implementacją. NET?

  6. Czy całkowicie się mylę z moim podejściem do tego problemu?

Wielkie dzięki,

Carl

Author: Tyst, 2009-06-02

6 answers

  1. Tak, 2128 wystarczająco długo.
  2. nie, implementacje GUID są zaprojektowane do generowaniaunikalnych GUID, a nie przypadkowych. Należy użyć kryptograficznie bezpiecznego generatora liczb losowych (np. RNGCryptoServiceProvider) aby wygenerować 16 losowych bajtów i zainicjalizować tym strukturę Guid.
  3. Tak, to akceptowalne podejście. Oba się sprawdzą.
  4. Tak, jeśli nie podasz żadnych innych wskazówek
  5. nie, goto 2
  6. Nie, to całkiem OK. Wystarczy użyć kryptograficznie bezpiecznego generatora liczb losowych, aby wygenerować GUID.
 11
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-21 23:57:24
  1. nie, identyfikatory GUID nie są w pełni losowe, a większość bitów jest albo statyczna, albo łatwo zgadywalna.
  2. Nie, Nie Są Przypadkowe, Patrz 1. W rzeczywistości istnieje bardzo mała liczba bitów, które są w rzeczywistości losowe, a nie kryptograficznie silne losowe w tym. Nie jest, Zobacz 1 i 2. Możesz, ale nie musisz... zobacz moje rozwiązanie na końcu.
  3. nie, patrz 1 i 2
  4. Tak.

To, czego powinieneś używać zamiast GUID, jest kryptograficznie silny generator liczb losowych-zastosowanie systemu .Ochrona.Kryptografia.Rngcryptoserviceprovider, aby wygenerować długi (powiedzmy 32 bajty) ciąg danych, następnie base64 zakodować to.
Ponadto, zakładając, że jest to jakiś rodzaj rejestracji z wrażliwymi danymi, chcesz ograniczyć Ważność linku, powiedzmy 60 minut lub 24 godziny - zależy od twojej witryny.
Musisz zachować mapowanie tych wartości do konkretnych użytkowników. Następnie możesz automatycznie przedstawić mu odpowiednie formularz w razie potrzeby. Nie musisz przepisywać adresu url, po prostu użyj go jako identyfikatora użytkownika (na tej stronie).
Oczywiście nie zapomnij, że ten adres URL powinien być HTTPS...

Btw, tylko uwaga-jego dobrą praktyką, aby umieścić jakąś formę tekstu w e-mailu, wyjaśniając, że użytkownicy nie powinni klikać na linki w anonimowych e-mailach, a zazwyczaj witryna nie będzie wysyłać, a oni nigdy nie powinni wprowadzać swojego hasła po kliknięciu blablabla....

Och, prawie zapomniałem - Kolejną kwestią, którą powinieneś rozważyć, jest to, co dzieje się tak, gdy użytkownik chce wysłać do niego kilka e-maili, np. kilka razy się rejestruje. Czy może to robić w kółko i uzyskać wiele ważnych adresów URL? Czy tylko ten ostatni jest ważny? A może ta sama wartość dostaje pretensje w kółko? Oczywiście, jeśli anonimowy użytkownik może złożyć prośbę o ten e-mail, To DoS może stać się problemem... nie wspominając o tym, że jeśli wpisze swój własny E-mail, może też wpisać dowolny losowy adres, zalewając skrzynkę odbiorczą jakiegoś biednego szmucka i prawdopodobnie powodując, że serwer pocztowy na czarną listę...
Nie ma jednej prawidłowej odpowiedzi, ale musi być brana pod uwagę w kontekście Twojej aplikacji.

 14
Author: AviD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-02 02:06:33

Może to być przesada, ale możesz hashować ich adres e-mail za pomocą SHA1 używając swojego guid (NewGuid jest w porządku) jako hash salt i umieścić go w adresie URL. Następnie, gdy pojawią się na twojej stronie, możesz poprosić ich o adres e-mail, pobrać identyfikator guid i ponownie obliczyć hash w celu weryfikacji. Nawet gdyby ktoś wiedział, jakie adresy e-mail wypróbować, nigdy nie byłby w stanie wygenerować kolizji hash bez znajomości guid, którym zasoliłeś (lub zajęłoby mu to cholernie dużo czasu długo:). Oczywiście trzeba by zapisać ich e-mail i hash salt guid w bazie danych.

 4
Author: JP Alioto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-02 05:57:01

Zalecałbym użycie zwykłej liczby losowej, np. bajtów z RNGCryptoServiceProvider.GetBytes . Guidy nie mają być całkowicie przypadkowe. Mają one stałe bity, a niektóre wersje używają twojego adresu MAC. GetBytes daje również możliwość użycia więcej niż 128 bitów (choć powinno to być dużo).

Myślę, że lepiej nie umieszczać danych użytkownika w adresie url. Chociaż HTTPS może go chronić podczas przesyłania, może nadal znajdować się w historii przeglądarki użytkownika lub tym podobne. On lepiej użyć POST i powiązać losową liczbę z wierszem bazy danych.

 4
Author: Matthew Flaschen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-02 05:58:27

Najpierw, jeśli to możliwe, powinieneś ograniczyć brute force, ograniczając przepustowość zapytania (np. ograniczone próby na IP na sekundę i ograniczone próby całkowite na sekundę).

W zależności od algorytmu generowania GUID, może to nie być dobry pomysł. Podczas gdy ostatnie wdrożenia powinny być "zwykle wystarczająco dobre", wartości mogą być przewidywalne. Ostatnie implementacje, jak ten używany w. NET zastosować hash, w przeciwnym razie masz wyraźnie identyfikowalne pola dla adresu MAC, i czas od startu. Jednak możliwe wartości są ograniczone, więc nie masz prawdziwych 128 losowych bitów.

Jeśli bezpieczeństwo jest priorytetem, wybrałbym silny kryptograficznie generator liczb losowych i zbudował ciąg losowych znaków. To również czyni oyu niezależnym od łatwego do odgadnięcia algorytmu (jako guid.ToString () jest łatwo zidentyfikowany jako taki) , dla którego atak może zostać wykryty w niedalekiej przyszłości.

Jeśli te kryteria są spełnione, nie widzę problemu w posiadanie klucza w łańcuchu zapytania.

 1
Author: peterchen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-02 05:55:45

Utwórz tabelę w bazie danych z linkID i kolumną Datesent, po wygenerowaniu linku send insert DateTime.Teraz do tabeli I return linkId, Ustaw linkID jako parametr querystring na activationLink. Po załadowaniu strony aktywacji Odzyskaj identyfikator linkId i użyj go do wywołania procedury składowanej, która zwróci datę, kiedy przekazałeś correspondin linkId jako parametr, po otrzymaniu daty z powrotem możesz dodać, jak długo chcesz, aby link pozostawał aktywny za pomocą .AddDays()/.AddMonths to są metody C # dla datetime. więc porównaj datę, którą masz z dzisiejszą datą. jeśli minęła długość dni lub miesięcy, wyświetl komunikat o błędzie lub kontynuuj i wyświetl zawartość strony. Sugeruję, że zachowasz zawartość strony w panelu i ustawisz vissible = "false", a następnie sprawisz, że panel będzie widoczny= "true", jeśli data jest nadal w zasięgu.

 -1
Author: Spegah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-05 17:28:22