Heartbleed (CVE-2014-0160) – błąd bezpieczeństwa w popularnej bibliotece kryptograficznej OpenSSL, obecny w jej wersjach wydanych między 14 marca 2012 a kwietniem 2014, który pozwalał na nieautoryzowany zdalny odczyt danych z pamięci operacyjnej dowolnego programu używającego tej biblioteki do obsługi szyfrowanych połączeń sieciowych. Był błędem implementacji rozszerzenia protokołu TLS/DTLS „Heartbeat”.

Umożliwiając kradzież obecnych często w pamięci programów, i krytycznie ważnych dla bezpieczeństwa, prywatnych kluczy kryptograficznych i danych dostępowych (haseł czy kluczy sesji), błąd narażał systemy na łatwe wtórne ataki typu przechwytywanie sesji czy man in the middle – podszywanie się pod usługi i użytkowników lub podsłuchiwanie ich, a tym samym na dostęp także do szyfrowanej komunikacji, prywatnych kont, usług i danych zapisanych w pamięci zewnętrznej.

Ze względu na powszechność stosowania OpenSSL i skalę zagrożenia, błąd określono jako bardzo poważny. Po czasie okazało się jednak, że nie wykorzystano go do wielu publicznie opisanych nadużyć.

Mechanizm działania Kontekst alt=Fragment interfejsu graficznego przeglądarki internetowej, na którym znajduje się symbol kłódki, reprezentujący stosowanie szyfrowanego połączenia.|mały|TLS jest standardem używanym m.in. do szyfrowania połączeń HTTPS ze stronami internetowym. Wiele przeglądarek używa ikony kłódki obok pola adresu do zasygnalizowania, że komunikacja jest w ten sposób chroniona. Protokoły SSL i TLS definiują powszechnie używane standardy kryptograficznej ochrony poufności i spójności danych w komunikacji sieciowej – sposób realizacji szyfrowanych połączeń w Internecie. Do 2012 standard TLS nie uwzględniał własnych funkcji związanych z długoterminowym utrzymywaniem połączeń. Komunikacja pozbawiona tej funkcjonalności może być wolniejsza, mniej płynna i bardziej wymagająca dla aplikacji – po zerwaniu lub zakończeniu jednej transmisji konieczna jest ponowna, pełna renegocjacja kolejnej. Nie dotyczyło to połączeń TLS opartych na samodzielnie rozwiązującym ten problem TCP, ale dotykało wariantu DTLS korzystającego z UDP. W lutym 2012 w dokumencie zaproponowano rozszerzenie protokołu o funkcjonalność „Heartbeat” (pol. „puls serca”) – wymiany próbnych komunikatów, podobnej do ping (na zasadzie „wezwanie – odzew”), wspomagających monitorowanie i podtrzymywanie połączenia, oraz przy okazji odświeżających tablice trasowania i translacji adresów na jego drodze.

Definicja Heartbeat wymaga, aby w wezwaniu określono odrębnie treść (maksymalnie bajtów) i długość żądanego odzewu w bajtach (jako uint16, czyli szesnastobitowa liczba naturalna, maksymalnie ) – w związku z możliwością stosowania zmiennego paddingu (dodatkowych bitów wydłużających pakiet). Zgodnie ze standardem, wezwania niespójne lub w inny sposób błędne muszą być ignorowane. Rozszerzenie zezwala też na korzystanie z mechanizmu Heartbeat na prawie każdym etapie połączenia (w tym przed próbą autoryzacji, która może być zapisana w logu).

Rozszerzenie Heartbeat zaimplementowano w programach korzystających z szyfrowanej komunikacji, oraz w bibliotekach programistycznych z gotowymi funkcjami kryptograficznymi udostępnianymi innym programom. Jedną z takich bibliotek rozwija nieodpłatnie, w modelu wolnego i otwartego oprogramowania, projekt OpenSSL. Korzystają lub korzystały z niej m.in. bardzo popularne serwery HTTP (Apache, nginx, Lighttpd, Tomcat), poczty elektronicznej (Sendmail, Postfix, Qmail, Exim, Dovecot, Zimbra), baz danych (MySQL, PostgreSQL, MongoDB), czy OpenVPN, OpenLDAP, a także program Bitcoin.

Błąd implementacji Implementacja w bibliotece OpenSSL, niezgodnie ze standardem, nie weryfikowała czy żądana treść i długość odzewu są zgodne – programista pominął konieczność sprawdzania zakresu. Wskutek tego, odpowiadała także na błędne wezwania do odesłania danego tekstu z długością przekraczającą jego faktyczny rozmiar. W takim przypadku nadal odsyłała zawartość nieprawidłowo określonego bufora – cały fragment pamięci operacyjnej o żądanej długości (do 64 KB), zaczynający się od praktycznie losowego adresu pod którym zapisano wyznaczoną odpowiedź, oraz znajdujące się po niej dowolne inne dane przechowywane tam aktualnie przez program – w tym potencjalnie wrażliwe informacje. Przy każdym żądaniu możliwy był wyciek ok. bajtów (64 KB) pamięci.

Choć mechanizm błędu nie pozwalał na celowy wybór adresu ujawnianej pamięci, wezwanie można było wysyłać wielokrotnie i do skutku. Ponieważ nie trzeba było przy tym zaczynać prób autoryzacji, ataki nie zostawiały z reguły śladu w standardowych logach. W praktyce, wykradana zawartość pamięci okazywała się różna w zależności od systemu – niektóre ujawniały natychmiast hasła, inne głównie nieprzydatne dane. W eksperymentach CERT Polska, badacze wysyłający żądania „Heartbleed” do różnych usług internetowych uzyskali w odpowiedzi fragmenty m.in. wiadomości e-mail, ciasteczek z kluczami sesji, danych dostępowych do VPN, konfiguracji serwerów sieci Tor (w tym ich ukrywanych adresów IP), czy logów serwera. Relacjonowali też, że inne osoby zdobyły tym sposobem inne dane dostępowe, czy fragmenty konfiguracji serwerów WWW, w tym plików .htaccess mogących zawierać dane autoryzacyjne.

Umożliwiona przez błąd kradzież kluczy prywatnych pozwalała na podszywanie się i odszyfrowanie zapisów starych transmisji (o ile nie podlegały technice utajniania z wyprzedzeniem). Kradzież ciasteczek sesyjnych pozwalała z reguły na bezhasłowe wejście na konto. Dzięki szybkiej dostępności gotowych skryptów po ujawnieniu podatności, wykonanie takich ataków było w ocenie ekspertów banalnie proste.

Historia alt=Okno terminala, w którym uruchomiono skrypt do wykorzystania podatności. W uzyskanej odpowiedzi serwera widać dane dostępowe.|mały|Symulowane wykorzystanie Heartbleed do uzyskania z serwera HTTP fragmentu pamięci, który zawiera login, hasło, i ciasteczko sesyjne użyte chwilę wcześniej przez obcego użytkownika serwisu. Definicję rozszerzenia Heartbeat opublikowano oficjalnie w lutym 2012 w dokumencie . Już pod koniec 2011 jeden z autorów RFC, Robin Seggelmann, wówczas doktorant w Fachhochschule Münster (Uniwersytet Nauk Stosowanych w Münsterze), przygotował implementację funkcji w rozwijanej w modelu wolnego i otwartego oprogramowania bibliotece OpenSSL. Po złożeniu przez Seggelmanna wniosku o dodanie wyniku jego pracy do kodu biblioteki, jego zmiany zostały sprawdzone przez Stephena N. Hensona, jednego z czterech głównych programistów i jedynego pełnoetatowego pracownika projektu. Henson nie zauważył błędu w implementacji i krótko przed północą 31 grudnia 2011 przyjął wadliwy kod do oficjalnego repozytorium. Błąd rozprzestrzenił się wraz z włączeniem rozszerzenia do wydania 1.0.1 OpenSSL 14 marca 2012. Funkcja „pulsu” była domyślnie włączona i nie podlegała konfiguracji, narażając na zagrożenie większość użytkowników wersji dotkniętych zmianą. Na błąd podatne były wersje od 1.0.1 do 1.0.1f oraz 1.0.2-beta i 1.0.2-beta1.

Po ujawnieniu błędu w kwietniu 2014, Seggelman przyznał się do jego autorstwa, tłumacząc to jako nieszczęśliwą programistyczną pomyłkę, i wspominał, że w tym czasie poprawiał wiele błędów i dodawał liczne nowe funkcjonalności do kodu. Likwidujące problem poprawki zostały uwzględnione we wszystkich wersjach biblioteki począwszy od 1.0.1g wydanej 7 kwietnia 2014.

Jak zwracali później uwagę komentatorzy, projekt OpenSSL był w tym czasie utrzymywany przez bardzo małą grupę wolontariuszy, spośród nielicznych ekspertów w niszowym i specjalistycznym temacie – dlatego kontrola jakości kodu była trudna. Przykładowo, Dan Kaminsky wskazywał, że projektowanie i implementacja bezpiecznych protokołów jest bardzo żmudną i niewdzięczną pracą, która przyciąga mało chętnych, choć to krytyczny element infrastruktury telekomunikacyjnej. Strona projektu wymieniała w tym czasie 15 aktywnych oficjalnych członków, z których jedynie Henson był zatrudniony na pełen etat. Wskazywano na relatywnie niski budżet projektu, nieproporcjonalny do ogromnej popularności biblioteki. OpenSSL otrzymywało wówczas ok. $2000 charytatywnych wpłat rocznie. Deweloperzy dorabiali dodatkowo do ok. $1 miliona łącznie jako konsultanci, jednak służyło to głównie ich prywatnemu utrzymaniu. Po ujawnieniu błędu inicjatywa Linux Foundation, z udziałem m.in. Facebooka, Google, IBM i Microsoftu, zdecydowała się zapewnić większe finansowanie dla podstawowej otwartoźródłowej „infrastruktury”, poczynając od OpenSSL.

Wykrycie Błąd pozostał prawdopodobnie niewykryty przez dwa lata. Pod koniec marca 2014 dwie niezależne grupy badaczy poświęcały uwagę jakości kodu OpenSSL. Neel Mehta z Google Security zajmował się, jak wspominał, żmudnym audytem tej biblioteki, zaniepokojony mniej poważnymi błędami w podobnych programach ujawnionymi wcześniej w 2014. Antti Karjalainen, Riku Hietamäki i Matti Kamunen z fińskiej firmy Codenomicon wykorzystywali OpenSSL do testów nowego fuzzera protokołów. Mehta odkrył błąd 21 marca lub wcześniej; od tego dnia Google zaczęło wprowadzać poprawki w swoich systemach. Zespół Codenomicon odkrył podatność 3 kwietnia (czasu fińskiego).