Najlepsze praktyki bezpieczeństwa losowych ciągów znaków

Losowe ciągi znaków to krytyczne prymitywy bezpieczeństwa. Prawidłowo używane dostarczają nieprzewidywalnych tokenów, które chronią sesje użytkowników i uwierzytelniają dostęp do API. Nieprawidłowo używane tworzą podatności, które atakujący wykorzystują. Ten przewodnik obejmuje niezbędne praktyki bezpieczeństwa.

Używaj kryptograficznie bezpiecznych generatorów

Najkrytyczniejszą decyzją bezpieczeństwa podczas generowania losowych ciągów znaków jest użycie kryptograficznie bezpiecznego generatora liczb losowych (CSPRNG). Nie można tego wystarczająco podkreślić: niekryptograficzne generatory jak Math.random() doprowadziły do rzeczywistych naruszeń bezpieczeństwa w systemach produkcyjnych.

CSPRNG są specjalnie zaprojektowane, aby opierać się przewidywaniu i analizie. Używają entropii ze źródeł, których atakujący nie mogą obserwować ani kontrolować: timing systemowy, zdarzenia sprzętowe, czujniki środowiskowe. Ta entropia seeduje algorytmy zaprojektowane tak, aby być obliczeniowo nieprzewidywalne lub nieodwracalne. Nawet jeśli atakujący obserwuje miliony wartości losowych, nie może przewidzieć przyszłych wartości ani określić przeszłych wartości.

Web Crypto API zapewnia crypto.getRandomValues() dla środowisk przeglądarkowych. W Node.js użyj crypto.randomBytes(). W Pythonie użyj modułu secrets (nie modułu random). W Javie użyj SecureRandom. W C# użyj RNGCryptoServiceProvider. Każda większa platforma zapewnia funkcje CSPRNG - używaj ich.

Math.random() i podobne niekryptograficzne generatory to deterministyczne algorytmy, które produkują sekwencje wyglądające na losowe, ale całkowicie przewidywalne. Są seedowane pojedynczą wartością, a cała sekwencja jest określona przez ten seed. Atakujący, którzy odkryją lub zgadną seed, mogą odtworzyć całą sekwencję, przewidując wszystkie "losowe" wartości. Te generatory są w porządku do symulacji, gier lub efektów wizualnych, ale katastrofalne dla bezpieczeństwa.

Rzeczywiste naruszenia wynikały z używania słabych generatorów liczb losowych. Tokeny sesji generowane przewidywalnymi RNG były wykorzystywane do przejmowania sesji użytkowników. Tokeny uwierzytelniające z niewystarczającą losowością umożliwiły nieautoryzowany dostęp. Jeden godny uwagi przypadek dotyczył podpisów ECDSA z przewidywalną losowością, co pozwoliło atakującym odzyskać klucze prywatne. Lekcja jest jasna: operacje kryptograficzne wymagają kryptograficznej losowości.

Weryfikacja, że Twój generator jest bezpieczny, wymaga sprawdzenia dokumentacji i kodu źródłowego. Upewnij się, że używasz kryptograficznych funkcji losowych, nie funkcji wygodnych, które mogą używać słabszych generatorów. W przeglądach kodu oznaczaj każde wrażliwe na bezpieczeństwo generowanie losowości, które nie używa jawnych funkcji CSPRNG. To nisko wiszący owoc, który zapobiega podatnościom o wysokiej wadze.

Wymagania entropii

Entropia kwantyfikuje nieprzewidywalność w bitach. Każdy bit reprezentuje binarny wybór - orzeł czy reszka, 0 lub 1. Ciąg znaków z n bitami entropii ma 2^n możliwych wartości. Więcej bitów wykładniczo zwiększa liczbę wartości, które atakujący musi spróbować w ataku brute-force.

Dla tokenów uwierzytelniających celuj w co najmniej 128 bitów entropii. To daje 2^128 możliwych wartości (około 340 undecylionów). Nawet przy trilionie prób na sekundę, brute-forcing 128 bitów entropii zajęłby miliardy razy więcej niż wiek wszechświata. To jest "obliczeniowo niewykonalne" - teoretycznie możliwe, ale praktycznie niemożliwe przy jakichkolwiek wyobrażalnych zasobach.

Identyfikatory sesji powinny używać minimum 112-128 bitów. Wytyczne OWASP zalecają co najmniej 64 bity, ale nowoczesne aplikacje powinny to przekraczać. Tokeny sesji to cele o wysokiej wartości - kompromitacja tokenu sesji daje natychmiastowy dostęp do konta użytkownika. Wyższa entropia zapewnia komfortowe marginesy bezpieczeństwa.

Klucze API zasługują na jeszcze wyższą entropię - 128-256 bitów. Klucze API często mają długi czas życia i szerokie uprawnienia. Mogą uwierzytelniać zautomatyzowane systemy wykonujące miliony żądań. Kombinacja długiego czasu życia, wysokich uprawnień i zautomatyzowanego użycia czyni je głównymi celami ataków brute-force, jeśli entropia jest niewystarczająca.

Tymczasowe kody mogą używać mniej entropii, jeśli szybko wygasają i mają ograniczenie częstotliwości. 6-cyfrowy kod numeryczny ma tylko 20 bitów entropii (log2(1 000 000) ≈ 20). To wydaje się niebezpiecznie niskie, ale w połączeniu z 5-minutowym wygasaniem i ograniczeniem częstotliwości po 3 nieudanych próbach staje się praktyczne. Ograniczone okno czasowe i limity prób sprawiają, że ataki brute-force są niewykonalne pomimo niskiej entropii.

Obliczanie wymaganej entropii zależy od scenariuszy ataku. Rozważ: Ile prób może atakujący wykonać na sekundę? Jak długo token będzie ważny? Jakie ograniczenie częstotliwości jest na miejscu? Jeśli atakujący może próbować 1000 tokenów na sekundę przez 24 godziny (86 400 sekund), może wykonać 86,4 miliona prób. Aby szansa sukcesu była znikoma, potrzebujesz wystarczającej entropii, żeby 86,4 miliona stanowiło znikomą część całkowitej przestrzeni. Przy 64 bitach entropii (2^64 ≈ 18 trylionów wartości), 86,4 miliona prób ma około 1 do 214 milionów szans na sukces.

Paradoks urodzinowy wpływa na prawdopodobieństwo kolizji dla identyfikatorów. Jeśli generujesz losowe ID i chcesz, aby prawdopodobieństwo kolizji było poniżej 1 do miliarda, gdy masz milion ID, potrzebujesz co najmniej 80 bitów entropii. Wzór to w przybliżeniu P ≈ n^2 / (2 * 2^b), gdzie P to prawdopodobieństwo kolizji, n to liczba ID, a b to bity entropii. Rozwiąż dla b na podstawie akceptowalnego P i oczekiwanego n.

Przechowywanie i transmisja

Generowanie bezpiecznych losowych ciągów znaków to tylko połowa sukcesu. Sposób ich przechowywania i transmisji określa, czy pozostaną bezpieczne, czy staną się podatnościami.

Nigdy nie przechowuj tokenów uwierzytelniających jako czysty tekst w swojej bazie danych. Jeśli Twoja baza danych zostanie naruszona, atakujący natychmiast mają wszystkie ważne tokeny. Zamiast tego haszuj tokeny przed zapisaniem za pomocą kryptograficznego hasha jak SHA-256. Podczas weryfikacji tokenu haszuj podany token i porównuj hasze. W ten sposób naruszenie bazy danych nie ujawnia użytecznych tokenów.

Dla tokenów sesji rozważ zaszyfrowane ciasteczka zamiast przechowywania po stronie serwera. Zaszyfrowane ciasteczka sesji przechowują dane sesji po stronie klienta, zaszyfrowane kluczem tajnym znanym tylko serwerowi. To eliminuje przechowywanie po stronie serwera i związane zapytania do bazy danych. Wymaga jednak starannej implementacji: używaj uwierzytelnionego szyfrowania (jak AES-GCM), starannie chroń klucze szyfrowania i ogranicz rozmiar ciasteczka.

Zawsze przesyłaj tokeny przez HTTPS, nigdy przez zwykłe HTTP. HTTP przesyła dane jako czysty tekst, pozwalając atakującym sieciowym przechwytywać tokeny przez ataki man-in-the-middle lub pasywne podsłuchiwanie. HTTPS szyfruje komunikację, chroniąc tokeny podczas transmisji. To nie jest negocjowalne dla żadnego tokenu używanego do uwierzytelniania lub autoryzacji.

Umieszczaj tokeny w nagłówkach autoryzacji zamiast parametrów URL, jeśli to możliwe. URL-e są logowane przez serwery webowe, serwery proxy i przeglądarki. Pojawiają się w historii przeglądarki i zakładkach. Są często udostępniane, gdy użytkownicy kopiują i wklejają URL-e. Umieszczenie tokenów w nagłówkach autoryzacji utrzymuje je poza logami i zapobiega przypadkowemu ujawnieniu przez udostępnione URL-e.

Klucze API w szczególności nie powinny nigdy pojawiać się w URL-ach ani kontroli wersji. Używaj zmiennych środowiskowych lub bezpiecznych systemów zarządzania konfiguracją. Regularnie rotuj klucze API i natychmiast, gdy mogą być skompromitowane. Wiele naruszeń bezpieczeństwa występuje, ponieważ deweloperzy commitują klucze API do publicznych repozytoriów GitHub, gdzie automatyczne skanery znajdują i wykorzystują je w ciągu minut.

Implementuj rotację tokenów dla długotrwałych sesji. Wydawaj krótkoterminowe tokeny dostępu (godziny) i dłuższe tokeny odświeżania (dni/tygodnie). Klienty używają tokenów odświeżania do uzyskania nowych tokenów dostępu bez ponownego uwierzytelniania. Jeśli token dostępu zostanie skompromitowany, wkrótce wygasa. Tokeny odświeżania mogą być jednorazowego użytku i unieważniają się, gdy są używane do uzyskania nowego tokenu dostępu. To ogranicza okno czasowe dla atakujących.

Monitoruj podejrzane użycie tokenów. Loguj, kiedy tokeny są używane, z jakich adresów IP, do jakich zasobów. Alarmuj o anomaliach: tokeny używane z wielu IP, nietypowe wzorce dostępu lub nieudane próby weryfikacji. Szybkie wykrycie i reakcja mogą ograniczyć szkody spowodowane przez skompromitowane tokeny.

Wypróbuj Narzędzie

Random String Generator

Random String Generator

Powiązane Artykuły