Preorder drugiego tomu książki sekuraka: Wprowadzenie do bezpieczeństwa IT. -15% z kodem: sekurak-book
Mechanizm HTTP Public Key Pinning
Bezpieczne połączenia przy użyciu protokołu HTTPS stanowią jeden z podstawowych budulców dzisiejszego Internetu. HTTPS zapewnia poufność, integralność oraz autentyczność komunikacji. Ten ostatni cel jest realizowany dzięki standardowi X.509, który definiuje infrastrukturę klucza publicznego. Model zaufania oparty na X.509 ma jednak pewną fundamentalną wadę, której rozwiązaniem ma być mechanizm HTTP Public Key Pinning (HPKP).
Jak działa X.509
Jak już wspomniano wyżej, X.509 definiuje infrastrukturę klucza publicznego, umożliwiając tym samym potwierdzenie, czy host, z którym próbujemy się połączyć, jest istotnie tym, za którego się podaje. Potwierdzenie autentyczności hosta odbywa się przy użyciu szeregu certyfikatów. Na samej górze mamy certyfikat główny (root certificate). Ten certyfikat należy do głównego urzędu certyfikującego (root CA) i jest samopodpisany (self-signed). Dzisiejsze systemy operacyjne oraz przeglądarki internetowe zawierają kilkadziesiąt zaufanych certyfikatów głównych.
Główne urzędy certyfikujące mogą uprawniać inne podmioty do działania w ich imieniu poprzez wygenerowanie im certyfikatów pośrednich (intermediate certificate), podpisując je kluczem prywatnym swojego certyfikatu głównego.
Zazwyczaj ścieżka certyfikacji dla stron internetowych składa się z trzech certyfikatów: certyfikatu głównego, jednego certyfikatu pośredniego oraz certyfikatu domeny. Sprawdzenie poprawności łańcucha certyfikatów odbywa się poprzez walidację podpisów cyfrowych każdego z nich. Jeśli walidacja się powiedzie, przeglądarka bądź system operacyjny uznają, że połączenie jest zaufane.
Gdzie tkwi problem w tym modelu? Mianowicie główne oraz pośrednie centra certyfikacji nie mają wyszczególnionych konkretnych domen, do których mogą wystawiać certyfikaty. Oznacza to, że każdy z tych podmiotów może wystawić zaufany certyfikat dla dowolnej domeny. Jak już wspomniano wyżej, głównych urzędów certyfikacji jest kilkadziesiąt, zaś, jak podała organizacja EFF (Electronic Frontier Foundation) w prezentacji z 2010 roku, w sumie wszystkich zaufanych podmiotów było 1482.
Głównym urzędom certyfikacji trudno utrzymać kontrolę nad wszystkimi z nich i czasem zdarzają się nadużycia. Najnowszy głośny przypadek tego typu pochodzi z marca 2015, gdy egipska firma MCS Holdings wystawiła nieautoryzowane certyfikaty dla kilku domen Google. Dzięki temu pracownicy firmy mogli przeprowadzić atak typu MiTM (man in the middle) na część użytkowników usług Google, którzy nie byliby tego świadomi, bowiem przeglądarka internetowa nie wyświetliłaby żadnego ostrzeżenia o błędnym certyfikacie.
Przypinanie certyfikatów
Aby rozwiązać opisany powyżej problem, w przeglądarkach Chrome oraz Firefox zaczęto stosować przypinanie certyfikatów (certificate pinning). Ten mechanizm pozwala określić, które urzędy certyfikacji są uprawnione do wystawienia certyfikatu dla danej domeny. Na przykład Google może zdefiniować, że wszystkie certyfikaty dla ich domen muszą zostać podpisane przez urząd certyfikacji Google Internet Authority G2. Gdy ten warunek nie zostanie spełniony, przeglądarka wyświetli ostrzeżenie (Rys 1.). Dzięki temu opisany wcześniej przypadek z wystawieniem fałszywego certyfikatu dla domen Google nie powiódłby się.
Mechanizm przypinania certyfikatów nie jest w żadnym wypadku nowym „wynalazkiem”; w Chrome jest stosowany już od 2011 roku. Dotychczas jednak polegał on na tym, że w przeglądarce zdefiniowano listę konkretnych domen oraz przypiętych certyfikatów.
Nagłówek HTTP Public-Key-Pins (HPKP)
W kwietniu 2015 r. została opublikowana finalna wersja RFC 7469, w którym zdefiniowano nagłówek odpowiedzi Public-Key-Pins, dzięki któremu właściciel dowolnej witryny internetowej może skorzystać z dobrodziejstw przypinania certyfikatów. Oto przykładowa wartość tego nagłówka:
Public-Key-Pins: pin-sha256="d6qzRu9zOECb90Uez27xWltNsj0e1Md7GkYYkVoZWmM="; pin-sha256="E9CZ9INDbd+2eRQozYqqbQ2yXLVKB9+xcprMF+44U1g="; pin-sha256="LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ="; max-age=10000; includeSubDomains
Poniżej opis poszczególnych dyrektyw:
- pin-sha256 – pole wymagane, odcisk palca jednego z certyfikatów z łańcucha (więcej o generowaniu wartości dla tego pola w dalszej części artykułu); RFC przewiduje, że w przyszłości mogą być używane inne algorytmy niż sha256, jednak na razie jest jedynym obsługiwanym; wartość hasha musi z kolei być enkodowana w base64,
- max-age – pole wymagane, czas ważności danego przypięcia w sekundach; innymi słowy: po upływie danego czasu przeglądarka przestanie traktować daną domenę jako używającą pinningu certyfikatów,
- includeSubDomains – pole opcjonalne. Domyślnie przypinanie certyfikatów działa tylko dla domeny, na której był obecny nagłówek Public-Key-Pins; dzięki użyciu tej dyrektywy przypinanie działa także dla wszystkich poddomen,
- report-uri – pole opcjonalne, pozwala zdefiniować adres, pod który przeglądarka zgłosi naruszenie certyfikatu.
Nagłówek Public-Key-Pins wygląda dość podobnie do HSTS (HTTP Strict Transport Security). Podobnie jak w przypadku HSTS, możliwe jest zdefiniowane trybu Report-Only (trzeba wówczas użyć nazwy nagłówka: Public-Key-Pins-Report-Only), w którym przeglądarka będzie tylko informować o wykryciu naruszeń certyfikatów, nie będzie zaś blokować dostępu do witryny.
Najistotniejszym polem z wyżej wymienionych jest pin-sha256, gdzie zdefiniowany jest odcisk palca jednego z certyfikatów z łańcucha. Jeżeli przeglądarka nie znajdzie w łańcuchu certyfikatów żadnego certyfikatu pasującego do jakiegokolwiek odcisku, nie pozwoli otworzyć danej witryny. Nie ma znaczenia, z którego certyfikatu weźmiemy odcisk; wybór jest w gestii administratora. Może zatem to być zarówno certyfikat głównego CA, jak i certyfikat domeny. Trudno jednoznacznie powiedzieć, który wybór jest najlepszy; jeśli jednak spodziewamy się, że często będziemy zmieniać certyfikaty, najsensowniej będzie wskazać albo certyfikat główny, albo pośredni.
Co istotne, RFC 7469 definiuje, że w nagłówku muszą znaleźć się co najmniej dwie dyrektywy pin-sha256, z czego co najmniej jedna nie może odwoływać się do żadnego certyfikatu z łańcucha certyfikatów. Innymi słowy: administrator witryny musi zdefiniować zapasowy pin (backup pin), który musi odnosić się do innego, jeszcze nieużywanego certyfikatu. Wprowadzenie pinów zapasowych jest uzasadnione potrzebą zapewnienia ciągłości działania strony internetowej. Wyobraźmy sobie sytuację, w której używany jest tylko jeden pin, a następnie, na przykład w wyniku jakiegoś incydentu bezpieczeństwa, certyfikat zostaje unieważniony. Administrator witryny generuje nowy certyfikat u innego dostawcy, jednak użytkownicy tak czy inaczej nie będą mogli jej odwiedzić ze względu na niezgodność pinów. Dzięki zastosowaniu zapasowego pinu problem zostaje rozwiązany, bowiem w razie incydentu bezpieczeństwa administrator natychmiast wystawia stronę z zapasowym certyfikatem, zaś wcześniej w nagłówku Public-Key-Pins umieszczono już jego odcisk palca.
Aby wygenerować odcisk palca dla certyfikatu, można posłużyć się poniższym poleceniem (zakładamy, że certyfikat znajduje się w pliku cert.pem):
openssl x509 -noout -in cert.pem -pubkey | openssl asn1parse -noout -inform pem -out /dev/stdout|openssl dgst -sha256 -binary /dev/stdin |openssl enc -base64
HPKP a proxy
Testerzy aplikacji internetowych często korzystają z aplikacji typu proxy (jak np. Burp czy Fiddler). Aby testować aplikacje działające w protokole HTTPS, najczęściej do lokalnego magazynu certyfikatów dodaje się certyfikat wygenerowany przez proxy. Teoretycznie mogłoby tutaj istnieć ryzyko, że testowanie witryn przestanie być możliwe, bowiem certyfikaty wystawione przez proxy na pewno nie znajdą się na liście certyfikatów przypiętych do domeny. Okazuje się, że zarówno Firefox, jak i Chrome domyślnie pomijają sprawdzanie pinów, jeżeli certyfikat głównego CA znajduje się w lokalnym, prywatnym magazynie certyfikatów.
W Firefoksie istnieje możliwość zmiany tego zachowania i wymuszenia bezwarunkowego sprawdzania pinów. Należy w tym celu ustawić w about: flags wartość flagi security.cert_pinning.enforcement_level na 2 (gdzie domyślną wartością jest 1).
Podsumowanie
Reasumując, mechanizm HTTP Public-Key-Pins (HPKP) pozwala mitygować ryzyko bezpośrednio związane z modelem X.509, które dowolnemu centrum certyfikacji pozwala wygenerować certyfikat dla każdej domeny. Dzięki nagłówkowi Public-Key-Pins administratorzy stron internetowych mogą sami określić, jakie certyfikaty są dopuszczalne.
Należy pamiętać, że HPKP wymaga posiadania pinu zapasowego. Najlepiej i najbezpieczniej jest, gdy pin odnosi się do zapasowego certyfikatu, wygenerowanego przez inne centrum certyfikacji niż ten używany na żywej witrynie. Ze względu na konieczność posiadania dwóch różnych certyfikatów, można się spodziewać, że mechanizm HPKP będzie używany raczej tylko w dużych wdrożeniach, takich jak np. systemy bankowe.
mb
Nie wiem czy dobrze rozumuję, ale jeżeli informacje o przypiętych certyfikatach są w nagłówkach (HPKP), to czy atakujący nie może zmodyfikować nagłówków?
To rozwiązanie nie zapewnia ochrony przy pierwszej wizycie tylko jeśli już na stronie kiedyś byłeś. Podobnie jak to ma miejsce w protokole SSH.
Ok, już wszystko jasne, dzięki za wyjaśnienie :-)
Moim okiem laika jest to tylko life hack. Dopiero jak obecny DNS zostanie zastąpiony czymś lepszym, będzie można mówić o zwiększeniu bezpieczeństwa.
Uargumentuj to proszę – obroń swoją tezę.
Co innego proponujesz zamiast HPKP?
Zawsze może zaatakować przez modyfikację nagłówków – czy to przed pierwszą wizytą czy przy kolejnych. Natomiast by atak był skuteczny musi umieć modyfikować nagłówki i tak zabawić się z przeglądarką oraz HPKP by go efektywnie wyłączyć jego ustawienia.
Zdradzę Wam pewien sekret – jeśli włamywacz potrafi otworzyć dany typ zamków to i tak warto je stosować niż zostawiać otwarte :)
No przy kolejnych to nie, chyba że chodzi ci że jak max-age wygaśnie.
Wygaśnie lub zostanie ustawione na małą wartość, czy nawet 0, który wyczyści ustawienia dla HPKP, a kolejnych już nie dopuszczę do przeglądarki. Zgadza się?
Zakładam sytuację, w której mogę manipulować nagłówkami HTTP w ramach połączenia szyfrowanego – co jest całkiem powszechne przy od lat funkcjonującym malware.
HPKP – juz sie z tego g… wycofuja.