Jak działa system biletowy
System biletowy - taki, który widzisz na festiwalach - działa w ten sposób: kiedy użytkownik płaci za bilet, do bazy danych dodawany jest wiersz z kolumną o nazwie
Gdy tylko strażnik na festiwalu zeskanuje kod kreskowy (zawierający identyfikator i unikalny hash) za pomocą swojego urządzenia, wysyłane jest żądanie do bazy danych, aby sprawdzić, czy:
- użytkownik pasujący do identyfikatora i skrótu zapłacił, oraz
- czy wartość kolumny
is_scanned
jest nadal ustawiona nafalse
.
Jeśli oba warunki są spełnione, ustawia wartość is_scanned
na true
, , aby zapobiec kopiowaniu biletu / kodu kreskowego przez inną osobę.
Problem z luką w zabezpieczeniach
Problem polega na tym, że czas między wysłaniem żądania przez urządzenie skanujące, a wartość is_scanned
jest przełączana z false
na true
.
Rozważ tę scenę rio: Alice ma ważny bilet, za który zapłaciła, ale potem pozwala Ewie skopiować jej kod kreskowy i zmienia widoczne imię na fałszywym bilecie z Alice na Eve. Więc teraz mamy dwa bilety. Jeden ważny i jeden fałszywy, ale oba mają ten sam kod kreskowy, jedyną różnicą jest nazwa.
A co, jeśli bilet Alicji i Ewy zostanie zeskanowany dokładnie w tym samym czasie, gdy wchodzą na festiwal ? System zgłoszeń nie przełączył is_scanned
na true
na czas, aby upewnić się, że Ewa nie może wejść z tym samym kodem kreskowym co Alice. Powoduje to, że oba bilety (ważne i fałszywe) są pokazywane strażnikom jako „ważne”.
Możliwe rozwiązania
Oczywiście tego rodzaju exploit naprawdę zależy od wielu szczęście, i chociaż teoretycznie jest to możliwe ... w prawdziwym scenariuszu prawdopodobnie by się to nie udało.
Jak jednak możemy pokonać tego rodzaju exploit również w teorii?
Identyfikacja
Ten exploit już wziąłem pod uwagę, używając następującej metody: Podczas skanowania kodu kreskowego wyświetlam nie tylko, czy bilet jest ważny (spełnia podane wcześniej warunki), ale także nazwa w bazie danych. Jeśli nazwa nie zgadza się z nazwą na bilecie, wiemy, że bilet jest w jakiś sposób manipulowany. Ponadto, jeśli imię i nazwisko, które pojawia się na urządzeniu skanującym, nie zgadza się z imieniem w identyfikatorze (które i tak każdy musi pokazać, aby udowodnić wiek), wpis jest również zabroniony.
obejście tego rozwiązania jest oszustwem tożsamości i oczywiście wykracza poza odpowiedzialność systemu biletowego za sprawdzenie.
Opóźnienie
Innym sposobem rozwiązania tego teoretycznie jest dodanie losowy czas opóźnienia między każdym żądaniem skierowanym do bazy danych / API walidacji. W ten sposób nikt nie byłby w stanie zeskanować biletu w tym samym czasie ... ponieważ czas walidacji jest za każdym razem opóźniany o losową ilość milisekund.
Nie jestem tego fanem , ponieważ:
- spowalnia wszystko przy wejściu
- nie jest efektywne, jeśli nie jest wystarczająco opóźnione. Ponieważ jeśli aktualizacja bazy danych
is_scanned
zfalse
dotrue
zajmie 50 ms, jedynym rozwiązaniem byłoby opóźnienie jej o minimum 50 ms za każdym razem.
Inne rozwiązania?
Jakie inne rozwiązania myślisz o rozwiązaniu tego exploita?