Prawdopodobnie słyszałeś o protokole HTTPS i o tym, jak zielona kłódka w przeglądarce daje nam spokój ducha. Jednak w świecie tworzenia aplikacji ślepe zaufanie do ważności certyfikatu nie zawsze wystarcza. Istnieje ukryte ryzyko, że nawet przy szyfrowanym połączeniu ktoś może potajemnie podsłuchiwać, co dzieje się między Twoim urządzeniem a serwerem.
Aby zaradzić tej luce w zabezpieczeniach, opracowano technikę zwaną przypinaniem certyfikatów (Certificate Pinning ). W skrócie, mówi ona naszej aplikacji: „Nie ufaj byle jakiemu urzędowi certyfikacji; akceptuj połączenie tylko wtedy, gdy serwer przedstawi ten konkretny certyfikat lub klucz publiczny”. To tak, jakby postawić bardzo surowego strażnika u drzwi naszej komunikacji.
Czym właściwie jest SSL Pinning i dlaczego go potrzebujemy?
Aby to dobrze zrozumieć, musimy najpierw pamiętać, że standardowy protokół HTTPS opiera się na łańcuchu zaufania . Po połączeniu z serwerem, wysyła on swój certyfikat cyfrowy. Urządzenie mobilne sprawdza, czy dokument został podpisany przez Urząd Certyfikacji (CA) zaufany przez system operacyjny. Jeśli podpis jest ważny, a certyfikat nie wygasł, połączenie zostaje nawiązane.
Problem pojawia się, gdy atakującemu udaje się zinfiltrować połączenie w trakcie transmisji, czyli w słynnym ataku typu Man-in-the-Middle (MITM) . Jeśli hakerowi uda się uzyskać od urzędu certyfikacji (CA) wydanie fałszywego, ale ważnego certyfikatu lub jeśli uda mu się zainstalować złośliwy certyfikat główny na urządzeniu ofiary, system operacyjny zatwierdzi połączenie. W tym momencie atakujący może przechwycić i zmodyfikować poufne dane, takie jak dane bankowe czy hasła, niezauważalnie dla użytkownika.
Tutaj właśnie pojawia się przypinanie. Zamiast ufać jakiemukolwiek uznanemu urzędowi certyfikacji, aplikacja przechowuje kopię certyfikatu serwera lub skrót klucza publicznego. Podczas uzgadniania porównuje otrzymany certyfikat z tym, który jest przechowywany. Jeśli certyfikaty nie są zgodne, połączenie jest natychmiast przerywane, co zapobiega podszywaniu się pod serwer.
Rodzaje kotwiczenia: certyfikaty kontra klucze publiczne
Nie każde przypinanie odbywa się w ten sam sposób. W zależności od tego, co zdecydujemy się „przypiąć”, mamy dwa główne podejścia. Pierwsze to przypinanie certyfikatów (Certificate Pinning ), w którym przechowujemy cały plik certyfikatu (.pem lub .der). Jest to najprostsza opcja do wdrożenia, ale najbardziej żmudna w utrzymaniu, ponieważ za każdym razem, gdy certyfikat serwera wygaśnie i zostanie odnowiony, będziemy musieli aktualizować aplikację w sklepie, w przeciwnym razie użytkownicy stracą dostęp do usługi.
Drugą opcją jest przypinanie klucza publicznego (Public Key Pinning ). W tym przypadku przechowujemy tylko skrót (zazwyczaj SHA-256) klucza publicznego certyfikatu. Główną zaletą jest to, że klucz publiczny może pozostać nienaruszony nawet po odnowieniu certyfikatu, co zapewnia nam większą elastyczność i zmniejsza częstotliwość wymuszonych aktualizacji aplikacji. Co więcej, przechowując tylko skrót, kod jest bardziej przejrzysty i trudniejszy do wydobycia przez osoby próbujące przeprowadzić inżynierię wsteczną.
Implementacja techniczna na różnych platformach
Jeśli pracujemy z AndroidNajnowocześniejszą metodą jest użycie pliku network_security_config.xmlW tym pliku XML definiujemy domeny i skróty certyfikatów (pinów), które chcemy autoryzować, co pozwala nam na: Aktywuj podstawowe ustawienia bezpieczeństwa na Androidzie natywnie. Następnie po prostu łączymy ten plik w AndroidManifest.xmlW przeszłości bardziej złożone rzeczy wykonywano poprzez nadpisywanie klasy. DefaultHttpClient i zarządzanie magazynami certyfikatów Java za pośrednictwem keytoolJednakże konfiguracja oparta o XML jest znacznie bardziej wydajna.
W ekosystemie iOSSytuacja nieco się zmienia. Możemy skorzystać z funkcji App Transport Security (ATS), konfigurując plik Info.plist Aby zdefiniować domeny zakotwiczone. Jednak w celu uzyskania pełnej kontroli, często stosuje się walidację w czasie wykonywania za pomocą URLSessionDelegateW metodzie wyzwania uwierzytelniania wyodrębniamy certyfikat z serwera i porównujemy go z lokalnie przechowywany certyfikat w pakiecie aplikacji.
Dla tych, którzy korzystają Kondensatory lub ramy hybrydoweIstnieją wtyczki takie jak @capgo/capacitor-ssl-pinning które ujednolicają proces. W takich przypadkach konfiguracja jest zazwyczaj przeprowadzana w pliku konfiguracyjnym aplikacji, gdzie określana jest lista certyfikatów i włączana jest walidacja. Kluczowe jest przetestowanie tych implementacji za pomocą narzędzi takich jak: Karol Prokurentsymulując atak MITM w celu potwierdzenia, że aplikacja skutecznie odrzuca połączenie, gdy certyfikat nie jest oczekiwany.
Ryzyka, ograniczenia i konserwacja
Przypinanie nie jest usłane różami. Największym zagrożeniem jest tzw. blokada wygaśnięcia . Jeśli certyfikat serwera wygaśnie, a aplikacja nie zostanie zaktualizowana nowym kodem PIN, wszyscy użytkownicy zobaczą błędy połączenia. Aby uniknąć tej katastrofy, najlepszym rozwiązaniem jest wdrożenie zapasowych kodów PIN . Przechowujemy skrót dodatkowego klucza publicznego, którego użyjemy tylko w nagłych wypadkach lub w przypadku nieoczekiwanej rotacji.
Z drugiej strony, przypinanie może być uciążliwe dla programistów, którzy muszą debugować swoją komunikację. Aby narzędzia monitorujące działały, czasami konieczne jest wyłączenie przypinania w środowiskach programistycznych lub utworzenie specjalnych wersji debugowych, zawsze upewniając się, że ta funkcjonalność jest włączona w wersji produkcyjnej docierającej do użytkownika końcowego.
Jeśli chodzi o internet, Chrome był pionierem we wdrażaniu podobnych koncepcji. Wykorzystuje on HSTS (HTTP Strict Transport Security) do egzekwowania protokołu HTTPS i utrzymuje listę „wstępnie załadowanych” witryn, aby zapobiec podatnościom pierwszego kontaktu. Chociaż standard HPKP istniał dla internetu, ostatecznie wyszedł z użycia, ponieważ był zbyt ryzykowny i mógł uniemożliwić dostęp do stron internetowych w przypadku wystąpienia błędu konfiguracji.
Wdrożenie funkcji przypinania certyfikatów to strategiczna decyzja, która równoważy maksymalne bezpieczeństwo z funkcjonalnością usługi. Ograniczając zaufanie do określonych podmiotów, chronimy komunikację przed wyrafinowanymi atakami, pod warunkiem zachowania ścisłej kontroli nad cyklem życia naszych kluczy i certyfikatów, aby uniknąć pozostawienia klientów bez dostępu.
