Audyt bezpieczeństwa (autor: Jean Philippe Aumasson)
12 stycznia 2020

Chcielibyśmy ogłosić, że Ergo pomyślnie przeszedł audyt bezpieczeństwa niektórych (najbardziej krytycznych) części kodu. Tym razem audyt został przeprowadzony przez Jean-Philippe Aumasson (aka veorq, https://aumasson.jp/ ).
Szczegółowy raport znajduje się poniżej. Nie znaleziono nic krytycznego. Uwagi dotyczące znalezionych problemów:
- W przypadku hasła portfela, w następnych wersjach klienta protokołu przedstawimy rekomendację. Nie jesteśmy pewni, czy wprowadzenie twardych wymagań dotyczących hasła będzie miało miejsce, ale przeprowadzimy więcej konsultacji w tej sprawie.
- Zmiana parametrów "n" i "k" ma sens tylko przy uruchamianiu nowej sieci. Zmiana tych parametrów w węźle górniczym spowoduje, że produkowane bloki będą nieważne dla innych węzłów. Zmiana tych parametrów w kliencie protokołu oznacza przejście na inny fork (bloki pochodzące od uczciwych uczestników protokołu będą odrzucane). Dlatego może nie ma potrzeby dodatkowych kontroli, ponieważ osoby uruchamiające nowe sieci ustawią "n" i "k" prawidłowo.
- Obecnie węzeł Ergo (jak również inne klientów protokołów blockchain i portfeli, o których wiemy, a także biblioteki kryptograficzne, których używamy) nie zapewniają ochrony przed atakami bocznymi działającymi lokalnie (np. ataki czasowe lub inspekcja pamięci przez złośliwe oprogramowanie lub wirusy). Dlatego prosimy o ochronę maszyn, na których uruchamiacie portfele!
==========================================================================================================
% Ocena bezpieczeństwa Ergo % Jean-Philippe Aumasson % 07/Dec/19
Podsumowanie
Zostaliśmy poproszeni przez Ergo o przeprowadzenie oceny bezpieczeństwa kilku komponentów ich platformy Ergo:
- Tworzenie i weryfikacja dowodów protokołu Sigma
- Bezpieczne przechowywanie sekretów w portfelu
- Walidacja Proof-of-Work
Niniejszy krótki raport podsumowuje naszą ocenę i opisuje nasze ustalenia oraz zalecenia dotyczące łagodzenia ryzyka.
Dowody protokołu Sigma
Protokół Ergo opiera się na ErgoScript, języku skryptowym wspierającym stwierdzenia sigma, które mogą być udowodnione i zweryfikowane za pomocą nieinteraktywnych dowodów wiedzy.
Te dowody są stwierdzeniami opisanymi jako drzewo warunków AND, OR i progowych, których liście są dowodami wiedzy o problemie logarytmu dyskretnego.
Dowód stwierdzenia sigma jest następnie czyniony nieinteraktywnym dzięki transformacji Fiat-Shamir.
Ta logika jest określona w dokumencie ErgoScript, a konkretne
ruty dowodzenia i weryfikacji opisane są w jego Załączniku A.
Wyzwania implementacyjne polegają na:
- Zdefiniowaniu kodowania dowodów, które są bezpieczne i wydajne, oraz wdrożeniu serializacji i deserializacji, które zawsze udaje się w przetwarzaniu prawidłowego wejścia, a które zawsze nieudolnie kończy się w przetwarzaniu nieprawidłowego wejścia.
- Poprawnym wdrożeniu funkcjonalności dowodzenia i weryfikacji, zgodnie ze specyfikacją, a co najważniejsze, tak, aby żadne nieprawidłowe stwierdzenie nie mogło pomyślnie przejść weryfikacji.
Przejrzeliśmy te dwa aspekty, opierając się na kodzie w repozytorium sigmastate-interpreter oraz na dokumencie ErgoScript, starannie porównując zamierzony zachowanie (w Załączniku A) z rzeczywistym zachowaniem, jak zostało zaimplementowane.
Szczególnie przejrzeliśmy kod z SigSerializer, Interpreter oraz ProverInterpreter cech i obiektów.
Głównie szukaliśmy błędów w następujących klasach:
- Niebezpieczne przetwarzanie źle sformułowanego wejścia
- Niebezpieczne przetwarzanie niezwykle długiego lub krótkiego wejścia
- Zachowanie przy dużej głębokości drzewa lub poziomie rekurencji
- Niebezpieczne użycie typów i struktur Scala
- Nieodpowiednie typy zmiennych
- Przepełnienia całkowite
- Warunki wyścigu
- Błędy logiczne
Pomimo szerokiego przeglądu, nie zidentyfikowaliśmy żadnych problemów z bezpieczeństwem.
Logika i wnętrze protokołu są jednak stosunkowo złożone, a najwyższe ryzyko widzimy w analizie i weryfikacji dowodów. Aby wykorzystać takie problemy, jednak, atakujący musiałby stworzyć semantycznie poprawny skrypt, który w jakiś sposób przynosiłby mu korzyści, a jednocześnie przechodziłby weryfikację, gdy nie powinien.
Jeśli chodzi o bezpieczeństwo oprogramowania, Scala eliminuje pewne klasy błędów, ale kod Scala może nadal cierpieć na błędy z powodu specyficznego zachowania Scala lub nieobsługiwanych błędów.
Portfel
Funkcjonalność portfela Ergo umożliwia użytkownikom przechowywanie sekretu na dysku i jego odzyskiwanie, inicjując portfel nowym seedem, gdy jest po raz pierwszy używany.
Ta logika jest głównie zdefiniowana w ErgoWalletActor, a kluczowym komponentem dotyczącym przechowywania sekretów jest JsonSecretStorage.
Za pierwszym razem, gdy portfel jest tworzony, polecenie InitWallet wykonuje następujące czynności:
- Generuje
settings.walletSettings.seedStrengthBitslosowych bitów, jako początkową entropię. Domyślnie generowane jest 160 bitów. - Generuje BIP39 z wygenerowanych losowych bitów, co można traktować jako kodowanie bitów entropii. Używana jest standardowa logika BIP39, z opcjonalnym hasłem.
- Wyprowadza seed z mnemoniki, używając logiki derivacji opartej na PBKDF2 BIP39.
- Szyfruje ten seed na dysku za pomocą AES-GCM, używając losowego nonce, oraz klucza wyprowadzonego z hasła przy użyciu PBKDF2-HMAC-SHA256 z 128000 iteracjami, używając losowej soli.
Aby odblokować już utworzony portfel, użytkownik podaje hasło, a portfel próbuje odszyfrować przechowywane dane.
Aby przywrócić istniejące konto z frazy BIP39, przeprowadzany jest podobny proces jak przy inicjalizacji, z tą różnicą, że portfel wyprowadzi seed z mnemoniki zamiast wybierać losową mnemonikę.
Dwa ryzyka, które zidentyfikowaliśmy tutaj, to:
- Brak kontroli długości hasła: ponieważ hasło jest wystarczające do uzyskania dostępu do seeda, biorąc pod uwagę sekret przechowywany na dysku portfela, hasło powinno w teorii mieć co najmniej tyle entropii, co mnemonika, a w praktyce powinno być praktycznie trudne do złamania. Dlatego zalecamy wprowadzenie minimalnej długości hasła, na przykład 16 znaków.
- Kopie wartości sekretów (hasło, seed i wyprowadzone klucze prywatne) mogą pozostać w pamięci po wykonaniu oprogramowania portfela, co jest wewnętrzną ograniczeniem języków z automatycznym zbieraniem śmieci, takich jak Scala.
Inny proces lub użytkownik dzielący tę samą przestrzeń adresową pamięci mógłby potencjalnie odzyskać sekrety, a także mogłyby one pojawić się w zrzutach awaryjnych. Na najlepszą naszą wiedzę, nie ma skutecznego łagodzenia w czystej Scali.
Walidacja PoW
Po wcześniejszym przeglądzie bezpieczeństwa Autolykos PoW, przeprowadziliśmy kolejny przegląd, koncentrując się na jego najnowszej logice weryfikacji, a w szczególności na zmianach w commicie eb0f85a.
Głównym istotnym plikiem jest AutolykosPowScheme, a inne ważne operacje są na przykład zaimplementowane w
HeadersProcessor oraz ModifierValidator.
Sprawdziliśmy, że zaimplementowana logika weryfikacji jest zgodna z tą określoną w specyfikacjach Autolykos i że jest prawidłowo zintegrowana w logice walidacji nagłówka bloku.
Uważamy, że następujące punkty powinny zostać rozwiązane:
- Surowsza walidacja
kin: chociaż klasa wymuszak<=32(liczba elementów w rozwiązaniu) in<31(log2 całkowitej liczby elementów), słabe mogłyby nadal być tworzone z dozwolonych parametrów. Funkcjavalidate()może zatem mieć dodatkową walidację, żeniksą równe zamierzonym
wartościom. - Upewnij się, że
kinsą wartościami dodatnimi, ponieważ obecnie ujemne (jakoInts) przechodziłyby przez instrukcjeassert.
Share post
13 sierpnia 2025
12 maja 2025






