Bezpieczeństwo web: Nagłówek HTTP Strict Transport Security (HSTS)

Protokół HTTPS jest dzisiaj powszechny na wszystkich stronach z wrażliwymi informacjami. Banki są klasycznym przykładem. HTTPS “gwarantuje”, że dane są przesyłane w szyfrowanej formie, a klient wie, że łączy się z oryginalną stroną. Certyfikat publikowany przez stronę jest gwarantem, że korzystamy właśnie z tej aplikacji, z której zamierzaliśmy. W najprostszej postaci wygląda to zatem następująco:

1

Tego przynajmniej spodziewamy się… Problem w tym, że czasami użytkownicy wpisują adres http://… W takich sytuacjach,  programiści przekierowują użytkownika na HTTPS, tzn. sekwencja wygląda następująco:

  1. Użytkownik wpisuje adres http://www.domain.com
  2. Serwer zwraca kod 302 – przekierowanie na https://www.domain.com
  3. Przeglądarka od teraz korzysta z bezpiecznej wersji czyli https://www.domain.com

Wygląda więc to następująco:

2

Niestety jest to bardzo niebezpieczna architektura. Bardzo dużo stron, włączając w to banki, korzysta z przekierowania na HTTPS.  Wiele banków korzysta z HTTP na stronie głównej, a do HTTPS jest użytkownik przełączony dopiero w momencie chęci zalogowania do strony. Oznacza to, że strona główna banku jest niebezpieczna.  Wszystko co na niej znajduje się może zostać podrobione (brak certyfikatu). Jeśli ktoś podmieni stronę główną i wstawi np. link do logowania do kompletnie innej strony,  możliwe, że staniemy się ofiarą phishing.

Wyobraźmy sobie, że korzystamy z Internetu w miejscu publicznym, np. używając WIFI. Możliwe, że ktoś wstawi proxy między nami, a docelowymi stronami.  Co jeśli staniemy się ofiarą ataku man in the middle? Taki serwer proxy będzie w stanie przekierowywać wszystkie nasze żądania. Wtedy powyższa sekwencja może wyglądać już tak:

  1. Użytkownik wpisuje http://www.domain.com
  2. Man in the middle przechwytuje żądanie i zwraca jakąkolwiek treść..
  3. Użytkownik nie zauważa nic podejrzanego. Strona wygląda identycznie – jesteśmy ofiarami phishing.

Czujny użytkownik zauważy, że po kliknięciu loguj na stronie głównej banku nie został przekierowany do https i wciąż korzysta z nieszyfrowanego protokołu. Niestety jest to rzadkość.

Problem jest jeszcze większy, ponieważ MITM (man in the middle), może rzeczywiście logować się do banku. Użytkownik poda hasło poprzez HTTP do MITM, a potem MITM nawiąże połączenie szyfrowane HTTPS z prawdziwą stroną banku. Możliwe jest zatem, że użytkownik będzie widział prawdziwe dane (balans konta itp), ale wszystko serwowane będzie przez MITM, który łączy się poprzez HTTPS z prawdziwym bankiem, a potem przekierowuje wszystko w postaci HTTP do użytkownika.

Rozwiązanie składa się z dwóch etapów. Przede wszystkim każdy bank powinien w pełni implementować HTTPS – na każdej podstronie.

Druga kwestia jest trudniejsza. Użytkownicy wciąż domyślnie będą wpisywać www.domain.com, a nie https://www.domain.com. Jak już wiemy, przekierowanie jest niebezpieczne bo nie wiadomo, czy ktoś po drodze nie przechwyci zapytania i nie będzie “karmił” nas dowolnymi danymi.

Z tego względu, wymyślono protokół HSTS (HTTP Strict Transport Security). Jest to protokół implementowany bezpośrednio przez przeglądarki. Jeśli serwer ustawi odpowiedni nagłówek, wtedy przeglądarka jest zobowiązana łączyć się zawsze przez HTTPS, a nie HTTP. Dzięki temu, MITM jest nie możliwy, ponieważ nigdy nie dojdzie do połączenia HTTP, a jak wiemy, dane przesyłane przez HTTPS nie mogą być zmodyfikowane.

Aby przeglądarka łączyła się zawsze przez https, serwer strony musi zwrócić następujący nagłówek w odpowiedzi:

Strict-Transport-Security:max-age=631138520; includeSubDomains; preload

Parametr max-age oznacza, jak długo przeglądarka ma łączyć się zawsze przez https. Powyższy nagłówek zawsze należy zwracać przez HTTPS, a nie przez HTTP. Wynika to z prostego faktu, że przeglądarka nie może ufać niczemu, co pochodzi z HTTP. Łatwo wyobrazić sobie, że przez HTTP, MITM modyfikuje np. max-age do 1.

Sekwencja może zatem teraz wyglądać następująco:
1. Użytkownik wpisuje http://www.domain.com
2. Serwer zwraca 302 oraz https://www.domain.com
3. Przeglądarka łączy się z https://www.domain.com
4. Serwer zwraca nagłówek Strict-transport-security.
5. Użytkownik wpisuje http://www.domain.com
6. Przeglądarka automatycznie przekierowuje na https://www.domain.com (kod 307, internal redirect). Od teraz MITM nie jest w stanie nam zaszkodzić, ponieważ nie wychodzi żadne połączenie HTTP.

Powyższe rozwiązanie ma jednak wciąż pewną lukę.Pierwsze połączenie HTTP wciąż jest niebezpieczne. Co prawda minimalizuje to groźbę ataku MITM ponieważ wystarczy, że użytkownik chociaż raz wcześniej korzystał ze strony (tak, że HSTS został ustawiony). Niestety w skrajnej sytuacji, wciąż mamy ten sam problem (MITM i pierwsze zapytanie z danej przeglądarki).

Z tego względu mamy tzw. pre-loaded lists. Przeglądarki korzystają z tych list i wtedy każda strona, która na niej znajduje się, będzie ładowana automatycznie wyłącznie przez HTTPS. Możemy naszą stronę dodać tutaj.
Po dodaniu do listy, przeglądarki będą łączyć się automatycznie przez HTTPS, nawet za pierwszym razem.
Możemy również zobaczyć adresy aktualnie dodanych stron do tych list.

W następnym wpisie, pokażę jak zaimplementować HSTS w ASP.NET MVC. W międzyczasie zachęcam zapoznać się z kompatybilnością różnych przeglądarek z HSTS .

2 thoughts on “Bezpieczeństwo web: Nagłówek HTTP Strict Transport Security (HSTS)”

  1. Witam Panie Piotrze, zastanawia mnie jedno zdanie
    “(…)Jeśli ktoś podmieni stronę główną i wstawi np. link do logowania do kompletnie innej strony, możliwe, że staniemy się ofiarą phishing.(…)”
    A gdyby strona była HTTPS, ktoś by ją podmienił i wstawił link do logowania do innej strony, to byłaby jakaś różnica ?

  2. @Piotr:
    Jesli strona bylaby HTTPS to po podmianie, wyskoczyl by blad w przegladarce – certyfikat (HTTPS) gwarantuje, ze strona nie zostanie podmieniona po drodze (suma kontrolna). Tresc jest szyfrowana, wiec man in the middle nie bedzie mogl w stanie nic zmienic bez spowodowania bledu w przegladarce.

Leave a Reply

Your email address will not be published.