Lista zmian: Projekt OWASP Top 10

Opublikowany: 2022-03-11

W ciągu ostatniej dekady złożoność aplikacji internetowych eksplodowała. Ewoluowały one od prostych kontenerów na formularze kontaktowe i ankiety do pełnowymiarowych aplikacji. Możemy je porównać do ciężkich aplikacji desktopowych, zarówno pod względem rozmiaru, jak i wydajności. Przy gwałtownym wzroście złożoności i rosnącej liczbie bogatych w funkcje aplikacji, konieczne stało się zainwestowanie dużej ilości czasu i uwagi w zapewnienie jak najbezpieczniejszych komponentów aplikacji. Masowy wzrost liczby użytkowników Internetu sprawił, że zajęcie się kwestią ochrony użytkowników danych i aplikacji stało się jeszcze ważniejsze. Istnieje ogromna pula zagrożeń, które próbują wkraść się i wywołać silne bóle głowy u wszystkich zaangażowanych.

W 2001 roku na scenę wkroczyła nowa organizacja. Jego celem była walka z problemami bezpieczeństwa dotykającymi strony internetowe i aplikacje. Został on odpowiednio nazwany Open Web Application Security Project (OWASP). Obecnie publikuje zasoby, organizuje konferencje, proponuje standardy bezpieczeństwa sieci i aplikacji. De facto standardem bezpieczeństwa aplikacji internetowych jest projekt OWASP Top Ten. Zawiera listę dziesięciu najbardziej rozpowszechnionych zagrożeń bezpieczeństwa. Czynnikami, które wpłynęły na to, co się dostało, była duża ilość danych i opinie społeczności. Pod koniec 2017 roku nastąpiła aktualizacja projektu. Kilka nowych kwestii krytycznych dla wielu nowoczesnych aplikacji internetowych znalazło swoje miejsce, a niektóre uciekły z listy.

Ten artykuł uzupełnia oryginalną listę i ilustruje najnowsze zmiany na liście. Opisuje zagrożenia, stara się podać jasne przykłady dla łatwiejszego zrozumienia i proponuje sposoby zwalczania zagrożeń bezpieczeństwa.

Problemy usunięte z listy 10 najlepszych OWASP

Przed aktualizacją z 2017 r. lista z 2013 r. była najświeższa. Biorąc pod uwagę zmiany w sposobie, w jaki aplikacje internetowe są teraz budowane i wykorzystywane, sensowne było jedynie dokonanie gruntownej zmiany. Mikroserwisy biorą swój kawałek tortu, a nowe fajne i błyszczące frameworki zastępują sprzęt bojowy z waniliowym kodem. Fakty te oznaczają, że niektóre z wymienionych wcześniej zagrożeń zostały usunięte, a na ich miejsce pojawiły się nowe.

W tym artykule odświeżymy naszą pamięć o dawno zapomnianych kwestiach, a także przedstawimy nowe złe wilki. Poznawanie historii to jedyny pewny sposób, aby nie powtarzać tych samych błędów.

Fałszerstwo żądań między witrynami

Cross-site request forgery (CSRF) jest jednym z „przegranych” w ostatniej iteracji projektu. Odszedł, ponieważ wiele nowoczesnych frameworków internetowych zawiera mechanizmy obronne CSRF. W ten sposób prawdopodobieństwo narażenia aplikacji na zagrożenie gwałtownie spada.

Niezależnie od tego, czy CSRF wyjdzie z listy, nadal dobrze jest odświeżyć naszą pamięć. Upewnijmy się, że nie wróci silniejszy niż kiedykolwiek.

W istocie CSRF jest exploitem, który sprawia wrażenie bomby dymnej. Atakujący nakłania niczego niepodejrzewającego użytkownika do wykonania niechcianego żądania lub działania w aplikacji internetowej. Mówiąc najprościej, atakujący zmusza swoją ofiarę do wysłania żądania do aplikacji innej firmy, a ofiara jest nieświadoma tego, że żądanie zostało kiedykolwiek wysłane. Żądanie może być żądaniem HTTP GET w celu pobrania zasobu lub, co gorsza, żądaniem HTTP POST, które zmienia zasób pod kontrolą ofiary. Podczas ataku ofiara myśli, że wszystko jest w porządku, najczęściej nawet nie zauważając, że coś dzieje się w tle. Gdy powietrze się przewietrzy, uszkodzenie jest lub czegoś brakuje i nikt nie wie, co się stało.

Skuteczne działanie pułapki umożliwia pomyślne wcześniejsze uwierzytelnienie użytkownika w aplikacji docelowej. Użytkownik w pewnym momencie przed atakiem zalogował się do aplikacji. Aplikacja wysłała ofierze plik cookie, aby ją zapamiętać. Gdy przeglądarka internetowa wyśle ​​złośliwe żądanie, plik cookie jest automatycznie wysyłany wraz z potencjalnym ładunkiem, a aplikacja nie sprzeciwia się obsłudze żądania użytkownikowi, którego już zna.

Jednym z najbardziej znanych przykładów jest nakłanianie użytkownika do przelania pieniędzy ze swojego konta na konto kontrolowane przez atakującego. Użytkownik loguje się do systemu bankowości elektronicznej, aby sprawdzić stan swojego konta. Następnie odwiedzają forum internetowe, aby sprawdzić recenzje nowego telefonu komórkowego. Atakujący, łowiąc dynamit, publikuje recenzję zawierającą obraz z pozornie uszkodzonym hiperłączem do obrazu. Zamiast prawdziwego hiperłącza, atakujący używa hiperłącza, którego system bankowości elektronicznej wewnętrznie wykorzystuje do przelewania pieniędzy z konta A na konto B: https://payments.dummybank.com?receiver=attacker&amount=100 . System bankowy czyni uwierzytelnionego użytkownika nadawcą, a wartość z parametru „odbiorca” odbiorcą środków. Oczywiście atakujący określa swoje konto zagraniczne jako odbiorcę.

Ponieważ przeglądarka automatycznie ładuje obrazy podczas renderowania strony, żądanie odbywa się w tle. Jeśli system płatności banku implementuje przekazy pieniężne za pomocą żądania HTTP GET, nic nie powstrzyma katastrofy. Zauważ, że przykład jest prosty i najprawdopodobniej transfery nie są obsługiwane przez HTTP GET. Atakujący może jednak z nieco większym trudem zmienić atrybut „akcja” w formularzu publikowania wiadomości HTML na forum. Przeglądarka wysyła żądanie do systemu płatności banku, a nie do zaplecza forum.

Kradzież pieniędzy to tylko jeden z wielu przykładów. Zmiana adresów e-mail użytkowników lub dokonywanie niezamierzonych zakupów również należą do tej kategorii. Jak to często bywa, socjotechnika i pewna wiedza techniczna są skuteczną dźwignią przeciwko błędom inżynierii oprogramowania.

Projektując swoje systemy, pamiętaj o następujących kwestiach:

  • Nie używaj żądań HTTP GET do enkapsulacji akcji, które modyfikują zasób. Tych próśb należy używać wyłącznie do pobierania informacji. Pamiętaj, że zasadą kciuka jest, aby żądania GET były idempotentne.
  • Czy , podczas przesyłania danych wewnętrznie za pomocą żądań HTTP POST, mają tendencję do wysyłania danych w formacie JSON, XML lub innym formacie innym niż kodowanie parametrów jako ciągu zapytania. Korzystanie z nietrywialnego formatu danych zmniejsza niebezpieczeństwo, że ktoś utworzy fałszywy formularz HTML, który wyśle ​​dane do Twojej usługi.
  • Upewnij się, że tworzysz i dołączasz unikalny i nieprzewidywalny token do swoich formularzy HTML. Te tokeny powinny być również unikalne dla każdego żądania. Sprawdzenie obecności i poprawności takich tokenów zmniejszy ryzyko wystąpienia zagrożeń. Aby znaleźć token i użyć go w swoich fałszywych żądaniach, osoby atakujące musiałyby uzyskać dostęp do Twojego systemu i pobrać token bezpośrednio z tego miejsca. Ponieważ tokeny są jednorazowe, nie można ich ponownie wykorzystać w złośliwym kodzie.

Ta podatność ma jeszcze gorszy efekt w połączeniu z cross-site scripting (XSS). Jeśli atakujący może wstrzyknąć złośliwy kod do ulubionej witryny lub aplikacji, zakres ataku staje się znacznie bardziej znaczący i niebezpieczny. Jeszcze bardziej krytyczne, atakujący mogą obejść niektóre mechanizmy ochrony przed CSRF, jeśli możliwe są ataki XSS.

Pamiętaj, że CSRF nie zniknął, po prostu nie jest tak powszechny, jak kiedyś.

Schemat CSRF w akcji — usunięty z top 10 OWASP

Niesprawdzone przekierowania i przekierowania

Wiele aplikacji po zakończeniu akcji przekierowuje lub przekierowuje użytkownika do innej części tej samej lub nawet innej aplikacji. Na przykład pomyślne zalogowanie się do aplikacji powoduje przekierowanie do strony głównej lub strony początkowo odwiedzonej przez użytkownika. Bardzo często miejsce docelowe jest częścią akcji formularza lub adresu linków. Jeśli komponent obsługujący przekierowanie lub forward nie upewni się, że adres docelowy jest rzeczywiście tym, który został wygenerowany przez aplikację, pojawia się potencjalne zagrożenie. Jest to luka w zabezpieczeniach o nazwie „niezweryfikowane przekierowania i przekierowania”.

Dwa główne powody, dla których niezatwierdzone przekierowania i przekierowania byłyby kiedykolwiek uważane za niebezpieczne, to phishing i przejmowanie danych uwierzytelniających. Atakujący może zmienić lokalizację docelową przekierowania/przekierowania i wysłać użytkownika do złośliwej aplikacji prawie nie do odróżnienia od oryginalnej. Niczego niepodejrzewający użytkownik ujawnia swoje dane uwierzytelniające i poufne informacje złośliwej stronie trzeciej. Zanim zorientują się, co się stało, jest już za późno.

Na przykład aplikacje internetowe bardzo często implementują logowanie z obsługą przekierowań do ostatnio odwiedzanej strony. Aby móc to łatwo zrobić, atrybut działania formularza HTML może wyglądać mniej więcej tak: http://myapp.example.com/signin?url=http://myapp.example.com/szczeniaki . Jesteś wielkim wielbicielem szczeniąt, więc sensowne było zainstalowanie rozszerzenia przeglądarki, które zastępuje favikony witryny miniaturami twoich ulubionych szczeniąt. Niestety jest to świat, w którym psy zjadają psy. Autor rozszerzenia przeglądarki postanowił zarobić na Twojej bezwarunkowej miłości i wprowadzić dodatkową „funkcję”. Za każdym razem, gdy odwiedzasz swoją ulubioną stronę fanów szczeniąt, zamienia ona parametr „url” w atrybucie działania formularza na link do ich własnej strony. Ponieważ strona wygląda dokładnie tak samo, kiedy podajesz dane swojej karty kredytowej, aby kupić karty do gry dla szczeniąt, w rzeczywistości finansujesz złośliwego napastnika, a nie swoje hobby.

Rozwiązanie luki polega na sprawdzeniu lokalizacji docelowej, upewniając się, że jest to zamierzona. Jeśli platforma lub biblioteka wykonuje pełną logikę przekierowania lub przekazywania dalej, warto sprawdzić implementację i w razie potrzeby zaktualizować kod. W przeciwnym razie musisz wykonać ręczne sprawdzenia, aby zabezpieczyć się przed atakiem.

Istnieje kilka rodzajów kontroli, które możesz wykonać. Aby uzyskać najlepszą ochronę, użyj kombinacji kilku podejść zamiast trzymać się tylko jednego z nich.

  • Sprawdź poprawność wychodzącego adresu URL, upewniając się, że wskazuje domenę, którą kontrolujesz.
  • Zamiast używać jawnych adresów, zakoduj je na interfejsie użytkownika, a następnie zdekoduj i zweryfikuj je na zapleczu.
  • Przygotuj białą listę zaufanych adresów URL. Umożliwia przekazywanie i przekierowania tylko do lokalizacji umieszczonych na białej liście. Wolę takie podejście do utrzymywania czarnej listy. Czarne listy są zwykle zapełniane nowymi przedmiotami tylko wtedy, gdy dzieje się coś złego. Białe listy są bardziej restrykcyjne.
  • Zastosuj podejście stosowane przez LinkedIn i niektóre inne aplikacje: zaprezentuj użytkownikom stronę z prośbą o potwierdzenie przekierowania/przekierowania, aby było jasne, że opuszczają Twoją aplikację.

Połączone problemy

Większość problemów na liście można określić jako defekty we wdrożeniu, spowodowane brakiem wiedzy lub niewystarczająco dogłębnym zbadaniem potencjalnych zagrożeń. Obydwa te powody można przypisać brakowi doświadczenia, a rozwiązanie do rozważenia ich w przyszłości jest łatwe – po prostu upewnij się, że uczysz się więcej i jesteś bardziej dokładny. Szczególnie trudna polega na połączeniu niebezpiecznej (ale bardzo ludzkiej) cechy polegającej na przyjmowaniu zbyt wielu założeń w połączeniu z trudnością w rozwijaniu i utrzymywaniu złożonych systemów komputerowych. Luka, która pasuje do tej kategorii, to „złamana kontrola dostępu”.

Uszkodzona kontrola dostępu

Luka jest spowodowana nieodpowiednim lub całkowitym brakiem autoryzacji i kontroli dostępu do niektórych części aplikacji. W poprzednich iteracjach projektu OWASP Top Ten wystąpiły dwa problemy: niezabezpieczone bezpośrednie odwołania do obiektów i brak kontroli dostępu na poziomie funkcji. Są teraz połączone w jedno ze względu na ich podobieństwo.

Bezpośrednie odniesienia do obiektów

Bezpośrednie odwołania do obiektów są często używane w adresach URL do identyfikowania zasobów, na których są operowane. Na przykład, gdy użytkownik się zaloguje, może odwiedzić swój profil, klikając łącze, które zawiera identyfikator jego profilu. Jeśli ten sam identyfikator jest przechowywany w bazie danych i jest używany do pobierania informacji o profilu, a aplikacja zakłada, że ​​użytkownicy mogą uzyskać dostęp do strony profilu tylko za pośrednictwem strony logowania, zmiana identyfikatora profilu w adresie URL ujawnia informacje o profilu innego użytkownika.

Aplikacja, która ustawia adres URL formularza usuwania profilu http://myapp.example.com/users/15/delete , wyjaśnia, że ​​w aplikacji jest co najmniej 14 innych użytkowników. Ustalenie, jak dostać się do formularza usuwania innych użytkowników, nie jest w tym przypadku nauką rakietową.

Rozwiązaniem tego problemu jest przeprowadzanie kontroli autoryzacji dla każdego zasobu bez zakładania, że ​​tylko niektóre ścieżki mogą być obrane w celu dostania się do niektórych części aplikacji. Ponadto usunięcie bezpośrednich odniesień i użycie pośrednich to kolejny krok naprzód, ponieważ utrudnia złośliwym użytkownikom zrozumienie, w jaki sposób tworzone jest odniesienie.

Podczas programowania, jako środek ostrożności, zapisz prosty diagram maszyny stanów. Niech stany reprezentują różne strony w aplikacji i przejścia, które mogą wykonywać użytkownicy. Ułatwia to wypisanie wszystkich przejść i stron, które wymagają szczególnej uwagi.

Ilustracja schematu maszyny stanowej

Brak kontroli dostępu na poziomie funkcji

Brak kontroli dostępu na poziomie funkcji jest bardzo podobny do niezabezpieczonych bezpośrednich odwołań do obiektów. W takim przypadku użytkownicy modyfikują adres URL lub inny parametr, aby spróbować uzyskać dostęp do chronionych części aplikacji. Jeśli nie ma odpowiedniej kontroli dostępu badającej poziomy dostępu, użytkownik może uzyskać uprzywilejowany dostęp do zasobów aplikacji lub przynajmniej pewną wiedzę o ich istnieniu.

Zapożyczając z przykładu dla bezpośrednich odwołań do obiektów, jeśli aplikacja zakłada, że ​​użytkownik odwiedzający formularz usuwania jest tylko superużytkownikiem, ponieważ superużytkownicy mogą zobaczyć łącze do formularza usuwania bez dokonywania dalszej autoryzacji, otwiera się ogromna luka w zabezpieczeniach. Liczenie na dostępność jakiegoś elementu UI nie jest właściwą kontrolą dostępu.

Problem można rozwiązać, zawsze sprawdzając wszystkie warstwy aplikacji. Interfejs frontonu może nie być jedynym sposobem, w jaki złośliwi użytkownicy mogą uzyskać dostęp do warstwy domeny. Nie należy też polegać na informacjach przekazywanych od użytkowników o ich poziomach dostępu. Przeprowadź odpowiednią kontrolę sesji i zawsze dwukrotnie sprawdzaj otrzymane dane. Tylko dlatego, że treść żądania mówi, że użytkownik jest administratorem, nie oznacza to, że tak naprawdę jest.

Uszkodzona kontrola dostępu łączy teraz wszystkie kwestie związane z niewystarczającą kontrolą dostępu, czy to na poziomie aplikacji, czy na poziomie systemu, jak błędna konfiguracja systemu plików.

Schemat złamanej kontroli dostępu

Nowe problemy na liście 10 najlepszych OWASP

Pojawienie się nowych frameworków front-end i przyjęcie nowych praktyk tworzenia oprogramowania przeniosło obawy dotyczące bezpieczeństwa na zupełnie nowe tematy. Nowe technologie rozwiązały również niektóre typowe problemy, z którymi wcześniej mieliśmy do czynienia ręcznie. Dlatego warto było zrewidować listę i dostosować ją do współczesnych trendów.

Jednostki zewnętrzne XML

Standard XML oferuje mało znaną ideę zwaną zewnętrzną encją, która jest częścią definicji typu danych (DTD) dokumentu. Pozwala autorom dokumentów na określenie linków do podmiotów zewnętrznych, do których można się odwoływać i umieszczać je w głównym dokumencie. Bardzo prostym przykładem byłoby:

 <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY> <!ENTITY bar "baz"> ]> <foo> &bar; </foo>

Podczas parsowania odwołanie &bar; jest zastępowane treścią ze zdefiniowanej encji, co daje <foo>baz</foo> .

Gdyby aplikacja korzystała z zewnętrznych danych wejściowych i umieszczała je bez żadnych kontroli bezpośrednio w definicji dokumentu XML, możliwa byłaby szeroka gama wycieków danych i ataków.

Magiczne jest to, że encja nie musi być prostym łańcuchem — może być odwołaniem do pliku w systemie plików. Parser XML chętnie weźmie zawartość określonego pliku i włączy ją do wygenerowanej odpowiedzi, potencjalnie ujawniając poufne informacje systemowe. Jak pokazuje OWASP, bardzo łatwo byłoby pozyskać informacje o użytkownikach systemu poprzez zdefiniowanie encji jako

 <!ENTITY xxe SYSTEM "file:///etc/passwd" >]>

Szczególnie kłopotliwą „cechą” tej luki jest możliwość łatwego wykonania ataku typu „odmowa usługi”. Jednym z łatwych sposobów na zrobienie tego byłoby wypisanie zawartości niekończącego się pliku, takiego jak /dev/random . Drugim jest stworzenie sekwencji bytów, z których każdy wielokrotnie odwołuje się do poprzedniego. To zamienia ostateczne odniesienie w korzeń potencjalnie bardzo szerokiego i głębokiego drzewa, którego parsowanie może wyczerpać pamięć systemową. Ten atak jest nawet znany jako Billion Laughs. Jak pokazano na Wikipedii, zdefiniowano szereg fikcyjnych podmiotów, co daje osobie atakującej możliwość włączenia miliarda lolów do ostatecznego dokumentu.

 <?xml version="1.0"?> <!DOCTYPE lolz [ <!ENTITY lol "lol"> <!ELEMENT lolz (#PCDATA)> <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;"> <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;"> <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;"> <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;"> <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;"> <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;"> <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;"> <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;"> ]> <lolz>&lol9;</lolz>

Zapobieganie wykorzystywaniu zewnętrznych jednostek XML można osiągnąć przy użyciu mniej złożonego formatu danych. JSON jest dobrym zamiennikiem, pod warunkiem, że zostaną podjęte pewne środki ostrożności ze względu na możliwe ataki na niego. Aktualizacja bibliotek XML jest koniecznością, w połączeniu z wyłączeniem przetwarzania zewnętrznych jednostek i DTD. Jak zawsze, zweryfikuj i oczyść dane pochodzące z niezaufanych źródeł przed ich użyciem lub włączeniem do dokumentów.

Niebezpieczna deserializacja

Pisząc kod, programiści mają możliwość kontrolowania systemów, które opracowują, za pomocą napisanego przez siebie kodu. Jak niesamowite byłoby kontrolowanie zachowania systemów innych firm, które piszą tylko niewielką ilość kodu lub nawet nie piszą go wcale? Dzięki temu, że ludzie nie są idealni, a biblioteki mają wady, jest to zdecydowanie możliwe.

Stan i konfiguracja aplikacji są często serializowane i przechowywane. Czasami przeglądarki służą jako silniki pamięci, jeśli serializowane dane są ściśle powiązane z bieżącym użytkownikiem. Aplikacja, która stara się być sprytna i oszczędzić czas przetwarzania, może użyć pliku cookie do oznaczenia, że ​​użytkownik się zalogował. Ponieważ plik cookie można utworzyć dopiero po pomyślnym zalogowaniu, sensowne jest zapisanie nazwy użytkownika w pliku cookie. Użytkownik jest następnie uwierzytelniany i autoryzowany na podstawie istnienia i zawartości pliku cookie. Gdyby ludzie nie mieli złych intencji, nic nie mogłoby pójść źle. Szczerze mówiąc, nie mogą też być ciekawi.

Jeśli ciekawski użytkownik znalazł plik cookie na swoim komputerze, mógł zobaczyć coś takiego:

 {"username": "joe.doe", "expires": "2018-06-01 10:28:16"}

Doskonale poprawny słownik Pythona zserializowany do formatu JSON, nic specjalnego. Zawsze ciekawski użytkownik może zmienić datę wygaśnięcia, aby aplikacja nie wymusiła wylogowania. Jeszcze bardziej zaciekawiony użytkownik może spróbować zmienić nazwę użytkownika na "jane.doe" . Gdyby ta nazwa użytkownika istniała, otworzyłaby zupełnie nowy świat dla niczego niepodejrzewającego użytkownika, który ma teraz dostęp do prywatnych danych.

Prosty przykład serializacji danych do formatu JSON i utrzymywania przejrzystości wszystkiego nie jest najgorszą rzeczą, jaka może Ci się przydarzyć. Jeśli atakujący zmodyfikuje niektóre zserializowane dane, może być w stanie zmodyfikować je w sposób, który zmusi system do wykonania dowolnego kodu.

Załóżmy, że tworzysz interfejs API REST, który umożliwia ludziom pisanie własnych modeli uczenia maszynowego w Pythonie i przesyłanie ich do Twojej usługi. Usługa oceni przesłane modele i przeszkoli je przy użyciu Twoich zestawów danych. Dzięki temu ludzie mogą korzystać z Twoich zasobów obliczeniowych i ogromnej ilości dostępnych zestawów danych do szybkiego i łatwego budowania modeli.

Usługa nie przechowuje kodu w formacie zwykłego tekstu. Użytkownicy zbierają swój kod, szyfrują go za pomocą swojego klucza prywatnego i wysyłają do API w celu przeszkolenia. Gdy usługa musi uruchomić model, odszyfrowuje kod, odszyfrowuje go i uruchamia. Trudne jest to, że protokół marynowania jest niebezpieczny. Kod można skonstruować w sposób umożliwiający wykonanie dowolnego złośliwego kodu podczas deserializacji.

Protokół pickle Pythona umożliwia klasom zdefiniowanie metody __reduce__ , która zwraca informacje o tym, jak deserializować niestandardowy obiekt. Jedną z obsługiwanych wartości zwracanych jest krotka dwóch argumentów: wywoływalna i krotka argumentów, które mają zostać przekazane do wywoływalnego. Biorąc pod uwagę, że Twój system uczenia modelu ML ma na celu zapewnienie maksymalnej elastyczności struktury kodu, możliwe jest napisanie następującego kodu:

 class Algo(object): def run(self): pass def __reduce__(self): import itertools return (list, (itertools.count(1), ))

Gdy obiekt wymaga deserializacji (odbarwienia), wywoływana jest list funkcji z tylko jednym argumentem. list funkcji jest konstruktorem listy w Pythonie, a funkcja itertools.count tworzy nieskończony iterator wartości, zaczynając od przekazanego parametru. Przekształcenie nieskończonego iteratora w skończoną listę może mieć katastrofalne skutki dla wydajności i stabilności systemu.

Jedynym prawdziwym lekarstwem na tego typu podatność jest rezygnacja z deserializacji danych pochodzących ze źródeł zewnętrznych. Jeśli nie jest to możliwe, sugeruje się użycie sumy kontrolnej lub podpisu cyfrowego, aby zapobiec deserializacji danych, które zostały potencjalnie zmodyfikowane przez złośliwego użytkownika. Spróbuj także skonfigurować środowisko piaskownicy oddzielone od głównego systemu, aby ograniczyć skutki problemów, które mogą się pojawić.

Korzystając z zewnętrznych bibliotek do deserializacji danych, na przykład z XML lub JSON, spróbuj wybrać te, które umożliwiają sprawdzenie typu obiektu przed wykonaniem rzeczywistej procedury deserializacji. Może to wychwycić nieoczekiwane typy obiektów, których jedynym celem jest uszkodzenie systemu.

Podobnie jak w przypadku wszystkich innych działań wykonywanych przez aplikację, wymuś obszerne rejestrowanie i monitorowanie. Deserializacje, które zdarzają się często lub zawodzą bardziej niż normalnie, są sygnałami, że dzieje się coś złego. Wyłap problemy wcześnie.

Niewystarczające rejestrowanie i monitorowanie

Ile czasu poświęcasz, aby upewnić się, że rejestrujesz wszystkie ostrzeżenia i błędy, które występują w Twojej aplikacji? Czy przechowujesz tylko błędy występujące w kodzie, czy też rejestrujesz błędy walidacji? Co się stanie, gdy zasady biznesowe Twojej domeny nie zostaną spełnione? Brak utrwalania wszystkich błędnych i podejrzanych działań w aplikacji stanowi zagrożenie dla bezpieczeństwa i danych.

Wyobraź sobie następujący scenariusz. Twoja aplikacja zawiera stronę logowania, tak jak większość. Formularz ma dwa pola, jedno na wpisanie adresu e-mail, a drugie na hasło. Jeśli użytkownik spróbuje się zalogować i poda nieprawidłowe hasło, może spróbować ponownie. Niestety liczba błędnych prób nie jest ograniczona, więc strona logowania nie zostanie zablokowana po N nieudanych próbach. Atakujący może wykorzystać tę okazję i, mając jeden poprawny e-mail, wprowadzać hasła z tęczowej tabeli, aż jedna kombinacja w końcu się powiedzie. Pod warunkiem, że Twoja aplikacja jest wystarczająco bezpieczna i haszujesz hasła przed wprowadzeniem ich do bazy danych, ten konkretny atak nie zadziała. Czy masz jednak mechanizm identyfikacji włamań?

Tylko dlatego, że ta jedna próba nie złamała Twojej strony logowania, nie oznacza to, że inna nie. Strona logowania prawdopodobnie nie jest też jedynym potencjalnym backdoorem, jaki masz. Gdyby nie coś innego, ktoś mógłby spróbować użyć przeciwko tobie złamanej kontroli dostępu. Nawet doskonale spreparowane aplikacje powinny wiedzieć, że ktoś próbuje je zaatakować, nawet jeśli nie jest to możliwe. Jednak zawsze tak jest.

Aby jak najlepiej zabezpieczyć się przed takimi atakami, wykonaj następujące czynności:

  • Rejestruj wszystkie awarie i ostrzeżenia występujące w aplikacji, czy to wyjątki zgłoszone w kodzie, czy błędy kontroli dostępu, walidacji i manipulacji danymi. Wszystkie przechowywane informacje muszą być replikowane i utrzymywane wystarczająco długo, aby możliwa była retrospektywna inspekcja i analiza.
  • Ważne jest określenie formatu i warstwy trwałości. Posiadanie ogromnego pliku o dowolnym formacie tekstowym jest łatwe do wykonania; przetwarzanie go później nie jest. Wybierz opcję przechowywania, która ułatwia przechowywanie i odczytywanie danych oraz format, który pozwala na łatwą i szybką (de)serializację. Przechowywanie JSON w bazie danych umożliwiającej szybki dostęp ułatwia użytkowanie. Utrzymuj małą bazę danych, regularnie tworząc jej kopię zapasową.
  • Jeśli masz do czynienia z ważnymi i cennymi danymi, zachowaj ślad działań, które można śledzić, aby sprawdzić stan końcowy. Zaimplementuj mechanizm zapobiegający ingerencji w dane.
  • Niech systemy działające w tle przeanalizują dzienniki i powiadomią Cię, jeśli coś się pojawi. Kontrole — które są tak proste, jak testowanie, czy użytkownik wielokrotnie próbuje uzyskać dostęp do chronionej części aplikacji — pomoc. Nie należy jednak przeciążać systemu fikcyjnymi testami. Systemy monitorowania muszą być uruchamiane jako oddzielne usługi i nie mogą wpływać na wydajność systemu głównego.

Podczas rozwiązywania problemu należy zwrócić szczególną uwagę, aby nie ujawnić dzienników błędów użytkownikom zewnętrznym. Niezastosowanie się do tego powoduje, że jesteś podatny na ujawnienie poufnych informacji. Logowanie i monitorowanie powinny pomóc Ci w rozwiązywaniu problemów, a nie atakującym w bardziej wydajnym wykonywaniu swojej pracy.

Schemat rejestrowania i monitorowania

Następne kroki

Świadomość potencjalnych zagrożeń i luk w aplikacjach internetowych jest ważna. Jeszcze ważniejsze jest, aby zacząć je identyfikować w swoich aplikacjach i zastosować poprawki, aby je usunąć.

Dbałość o bezpieczeństwo aplikacji jest ważną częścią wszystkich etapów projektu rozwoju oprogramowania. Architekci oprogramowania, programiści i testerzy muszą uwzględniać procedury testowania oprogramowania w swoich przepływach pracy. Korzystne jest wykorzystanie list kontrolnych bezpieczeństwa i automatycznych testów na odpowiednich etapach procesu tworzenia oprogramowania w celu zmniejszenia ryzyka bezpieczeństwa.

Niezależnie od tego, czy analizujesz istniejącą aplikację, czy tworzysz nową, powinieneś przyjrzeć się projektowi OWASP Application Security Verification Standard Project (ASVS). Celem projektu jest opracowanie standardu weryfikacji bezpieczeństwa aplikacji. Standard wylicza testy i wymagania dotyczące tworzenia bezpiecznych aplikacji internetowych. Testom przypisuje się poziomy od jednego do trzech, gdzie jeden oznacza najmniejsze zagrożenie, a trzy najwyższe potencjalne zagrożenie. Klasyfikacja pozwala menedżerom aplikacji zdecydować, które z zagrożeń są bardziej prawdopodobne i ważne. Nie ma potrzeby dołączania każdego testu do każdej aplikacji.

Zarówno nowe, jak i istniejące projekty aplikacji internetowych, zwłaszcza te, które działają zgodnie z zasadami Agile, korzystają ze zorganizowanego planowania działań mających na celu zabezpieczenie ich aplikacji. Planowanie testów OWASP ASVS jest łatwiejsze, jeśli zdecydujesz się na użycie OWASP Security Knowledge Framework. Jest to aplikacja do zarządzania sprintami zorientowanymi na testy bezpieczeństwa, zawierająca zestaw przykładów rozwiązywania typowych problemów związanych z bezpieczeństwem oraz łatwe do wykonania listy kontrolne oparte na OWASP ASVS.

Jeśli dopiero zacząłeś odkrywać bezpieczeństwo aplikacji internetowych i potrzebujesz bezpiecznego środowiska sandbox, skorzystaj z implementacji aplikacji internetowej firmy OWASP — WebGoat. Jest to celowo niebezpieczna implementacja aplikacji internetowej. Aplikacja poprowadzi Cię przez lekcje, przy czym każda lekcja koncentruje się na jednym zagrożeniu bezpieczeństwa.

Podczas tworzenia aplikacji upewnij się, że:

  • Identyfikuj zagrożenia i ustalaj ich priorytety. Zdefiniuj, które zagrożenia mogą realnie wystąpić i stanowić zagrożenie dla Twojej aplikacji. Ustal priorytety zagrożeń i zdecyduj, które z nich zasługują na najwięcej wysiłku związanego z tworzeniem i testowaniem. Nie ma sensu wkładać wiele wysiłku w rozwiązanie problemu niewystarczającego rejestrowania i monitorowania, jeśli obsługujesz statyczny blog.
  • Oceń architekturę i projekt swojej aplikacji. Niektóre luki są bardzo trudne do usunięcia w późniejszych fazach tworzenia aplikacji. Na przykład, jeśli zamierzasz wykonać kod innej firmy i nie planujesz korzystania ze środowiska piaskownicy, bardzo trudno będzie obronić się przed niezabezpieczonymi atakami deserializacji i wstrzykiwania.
  • Zaktualizuj proces tworzenia oprogramowania. Testowanie pod kątem zagrożeń aplikacji internetowych musi być w miarę możliwości procesem zautomatyzowanym. Korzystne jest rozszerzenie przepływów pracy CI/CD o automatyczne testy próbujące znaleźć luki w zabezpieczeniach. Możesz nawet wykorzystać istniejący system testów jednostkowych do opracowania testów bezpieczeństwa i okresowego ich uruchamiania.
  • Ucz się i ulepszaj. Lista problemów i luk w zabezpieczeniach nie jest statyczna i zdecydowanie nie ogranicza się do dziesięciu czy piętnastu zagrożeń. Nowa funkcjonalność i pomysły otwierają drzwi dla nowych rodzajów ataków. Ważne jest, aby przeczytać o aktualnych trendach w świecie bezpieczeństwa aplikacji internetowych, aby być na bieżąco. Zastosuj to, czego się uczysz; w przeciwnym razie marnujesz swój czas.

Wniosek

Chociaż, jak sugeruje nazwa, projekt OWASP Top Ten wymienia tylko dziesięć luk w zabezpieczeniach, istnieją tysiące możliwych pułapek i backdoorów zagrażających twoim aplikacjom, a co najważniejsze, twoim użytkownikom i ich danym. Bądź czujny i stale odświeżaj swoją wiedzę, ponieważ zmiany i ulepszenia technologii mają zarówno plusy, jak i minusy.

Aha, i nie zapominaj, że świat nie jest czarno-biały. Luki w zabezpieczeniach nie pojawiają się same; często są ze sobą powiązane. Bycie narażonym często oznacza, że ​​garść innych jest za rogiem, czekając, aby podnieść swoje brzydkie głowy, a czasami, nawet jeśli to nie twoja wina, jako twórca zabezpieczeń systemu, nadal masz załatać luki, aby ograniczyć cyberprzestępczość. Aby zapoznać się z przykładem, zobacz Zhakowane numery kart kredytowych nadal obsługują Google .