Czym jest PKCE: od podstawowych pojęć do głębokiego zrozumienia
Ten artykuł wyjaśnia, jak PKCE (Proof Key for Code Exchange) zabezpiecza przepływ kodu autoryzacyjnego OAuth 2.0 poprzez zapobieganie przechwytywaniu kodów autoryzacyjnych przez złośliwe aplikacje, prowadząc Cię od podstawowych pojęć do kompleksowego zrozumienia.
Proof Key for Code Exchange (PKCE) to rozszerzenie przepływu kodu autoryzacyjnego, które pierwotnie zostało zaprojektowane do zabezpieczania przepływu kodu autoryzacyjnego w aplikacjach mobilnych, a teraz jest zalecane również dla aplikacji jednostronicowych. Od OAuth 2.1, PKCE jest wymagane dla wszystkich typów klientów, w tym klientów publicznych i klientów poufnych (prywatnych).
W tym artykule pomożemy Ci zrozumieć, dlaczego PKCE zostało stworzone i jak chroni Twoje aplikacje, dając Ci głębokie zrozumienie PKCE.
Dlaczego PKCE jest potrzebne?
W przepływie kodu autoryzacyjnego OAuth 2.0 użytkownicy proszą o zalogowanie się za pośrednictwem aplikacji. Serwer uwierzytelniania kieruje użytkowników na stronę uwierzytelniania. Po uwierzytelnieniu użytkownika serwer zwraca kod autoryzacyjny do aplikacji, która następnie używa tego kodu do zażądania tokena dostępu od serwera uwierzytelniania.
Ten przepływ ma znaczące ryzyko bezpieczeństwa: kod autoryzacyjny może być przechwycony przez złośliwe programy. Jest to szczególnie niepokojące na urządzeniach mobilnych, gdzie inne aplikacje mogą zarejestrować ten sam URI przekierowania i przechwycić kod autoryzacyjny.
Proces przechwytywania przedstawiony jest na diagramie poniżej:
Krok (1): Aplikacja wykonuje żądanie autoryzacji poprzez bezpieczne API, które nie może być przechwycone. W tym kroku żądający również podaje URI przekierowania.
Krok (2): Żądanie zostaje następnie przekazane do serwera autoryzacyjnego OAuth 2.0. Ponieważ OAuth wymaga użycia TLS, ta komunikacja jest chroniona przez TLS i nie może być przechwycona.
Krok (3): Serwer autoryzacyjny zwraca kod autoryzacyjny.
Krok (4.a): kod autoryzacyjny jest zwracany do żądającego poprzez URI przekierowania, który został podany w kroku (1). W tym kroku, jeśli złośliwa aplikacja zarejestrowała się jako obsługująca URI przekierowania, wówczas złośliwa aplikacja może przechwycić kod autoryzacyjny. Z kodem autoryzacyjnym napastnik może żądać i uzyskać token dostępu w krokach (5.a) i (6.a), odpowiednio.
Jak pokazano powyżej, w przepływie kodu autoryzacyjnego OAuth 2.0, jeśli kod autoryzacyjny zostanie przechwycony, atakujący może go użyć do uzyskania tokenów dostępu. Dlatego potrzebujemy mechanizmu, który zapobiegałby przechwytywaniu kodu autoryzacyjnego, co doprowadziło do stworzenia PKCE.
Jak działa PKCE?
Jak wspomniano powyżej, jeśli chcemy zapobiec atakom, musimy upewnić się, że tylko aplikacja, która zainicjowała żądanie, może żądać i uzyskać token dostępu. To tutaj wkracza PKCE.
PKCE rozwiązuje ten problem poprzez wprowadzenie koncepcji "proof key" (klucz dowodu).
Podczas żądania kodu autoryzacyjnego aplikacja najpierw generuje losowy weryfikator kodu i przechowuje go lokalnie. Następnie przekształca ten weryfikator kodu w wyzwanie kodu za pomocą określonych algorytmów. Aplikacja wysyła zarówno wyzwanie kodu, jak i metodę wyzwania kodu do serwera uwierzytelniającego podczas żądania kodu autoryzacyjnego.
Weryfikator kodu to losowo generowany ciąg, a wyzwanie kodu jest wyprowadzone z weryfikatora kodu poprzez przekształcenie. Obsługiwane są dwa metody przekształcenia:
plain
: Używa weryfikatora kodu bezpośrednio jako wyzwania kodu
S256
: Stosuje haszowanie SHA-256 do weryfikatora kodu, a następnie kodowanie Base64URL. Ponieważ wynik haszowania nie może być odwrócony w celu uzyskania weryfikatora kodu, a metodaplain
może być podatna na ataki typu man-in-the-middle podczas transmisji, zaleca się stosowanieS256
z powodów bezpieczeństwa.
Po uwierzytelnieniu użytkownika serwer uwierzytelniający zwraca kod autoryzacyjny do aplikacji. Podczas żądania tokena dostępu aplikacja wysyła zarówno kod autoryzacyjny, jak i weryfikator kodu do serwera uwierzytelniającego. Serwer przekształca "weryfikator kodu" za pomocą wcześniej otrzymanej "metody wyzwania kodu" i porównuje rezultat z wcześniej otrzymanym "wyzwaniem kodu", aby zweryfikować posiadanie "weryfikatora kodu" przez klienta.
Krok (1-3): Aplikacja tworzy i zapisuje tajny weryfikator kodu i przekształca go w "wyzwanie kodu", które jest wysyłane w żądaniu autoryzacji OAuth 2.0 razem z metodą przekształcenia "metodą wyzwania kodu".
Krok (3-6): Serwer uwierzytelniający odpowiada jak zwykle, ale zapisuje "wyzwanie kodu" i "metodę wyzwania kodu".
Krok (7.a): Aplikacja wysyła następnie kod autoryzacyjny do punktu końcowego tokena jak zwykle, ale dołącza tajny "weryfikator kodu" wygenerowany w kroku (1).
Krok (8.a-9.a): Serwer autoryzacyjny przekształca "weryfikator kodu" w "wyzwanie kodu" i porównuje go z "wyzwaniem kodu" z kroku (1-3). Dostęp jest odmówiony, jeśli nie są równe.
W tym przypadku, nawet jeśli złośliwa aplikacja przechwyciła kod autoryzacyjny w kroku (6.b), nie jest w stanie wykorzystać go do zdobycia tokena dostępu, ponieważ nie posiada tajnego "code_verifier", a ponieważ "weryfikator kodu" jest przesyłany za pomocą TLS, nie może być przechwycony.
Podsumowanie
Ten artykuł wyjaśnia, jak działa PKCE i dlaczego jest niezbędne do ochrony przepływu kodu autoryzacyjnego. Dzięki wprowadzeniu mechanizmu klucza dowodu, PKCE zapobiega przechwytywaniu i nadużywaniu kodów autoryzacyjnych przez złośliwe aplikacje. Mam nadzieję, że to wyjaśnienie pomogło Ci zrozumieć PKCE w głębi.