Testy bezpieczeństwa — czym są i dlaczego powinniśmy przeprowadzać je regularnie?

Bezpieczeństwo systemów i aplikacji jest kluczowym aspektem w dzisiejszym środowisku cyfrowym. Jakiekolwiek problemy i incydenty w tym zakresie mogą prowadzić do wycieku danych, naruszeń prywatności, utraty zaufania użytkowników oraz znaczących strat finansowych. Dlatego tak ważne jest, aby projektować, rozwijać i utrzymywać oprogramowanie zgodnie z najlepszymi praktykami, regularnie przeprowadzać testy bezpieczeństwa systemów informatycznych oraz monitorować całą infrastrukturę IT, pamiętając, jak ważna jest prawidłowa ocena podatności. W końcu cel jest jasny: zapewnienie bezpieczeństwa każdego użytkownika systemu.

Testy bezpieczeństwa - czym są i dlaczego powinniśmy przeprowadzać je regularnie?

Czym są testy bezpieczeństwa?

Jest to kontrolowany proces, mający na celu wykrycie jak największej liczby błędów, które mógłby wykorzystać potencjalny atakujący w celu uzyskania nieuprawnionego dostępu do danych. W uproszczeniu, testerzy bezpieczeństwa wcielają się w rolę atakujących i przy zachowaniu etyki działania, przeprowadzają testy penetracyjne, próbując przełamać zabezpieczenia systemu.

Następnie przedstawiają z tego raport, który zawiera listę znalezionych problemów bezpieczeństwa wraz z rekomendacjami ich rozwiązania i zwiększenia ochrony.

Testy bezpieczeństwa mają na celu podniesienie ogólnego bezpieczeństwa aplikacji czy systemu, aby zmniejszyć ryzyko potencjalnego ataku.

Warto zaznaczyć, że przeprowadzenie testów bezpieczeństwa nie gwarantuje 100% ochrony, lecz zmniejsza możliwą powierzchnię ataku — testerzy mają z góry określony czas na znalezienie luk w zabezpieczeniach, kiedy to potencjalni atakujący dysponują nieograniczonymi zasobami czasowymi.

Ponadto testy bezpieczeństwa powinny być regularnie powtarzane ze względu na stały rozwój aplikacji. Warto pamiętać, że każda zmiana może wprowadzić błąd bezpieczeństwa i „otworzyć drzwi” przed potencjalnymi zagrożeniami.

Testy penetracyjne. Manualne a narzędzia automatyczne

Testy bezpieczeństwa mogą być wspierane poprzez narzędzia automatyczne. Można je podzielić na dwa podstawowe typy:

  • Testy statyczne (SAST) — stosują podejście typu „whitebox” – wymagają dostępu do kodu źródłowego aplikacji / plików konfiguracyjnych. Nie wymagają uruchomionej „żywej” aplikacji. Takie automatyczne skany są szybkie, jednakże często wiążą się z dużą liczbą „false positive’ów”, które należy manualnie zweryfikować. Narzędzia automatyczne tego typu mogą być w łatwy sposób integrowane w procesie CI/CD, a nawet podczas tworzenia kodu w środowiskach IDE. Przykładem takich narzędzi są: SonarQube, SonarLint.
  • Testy dynamiczne (DAST) — stosują podejście typu „blackbox” – wymagają uruchomionej aplikacji. Nie wymagają dostępu do kodu źródłowego aplikacji / plików konfiguracyjnych. Testy dynamiczne korzystają z realnej infrastruktury aplikacji. Umożliwiają szersze spektrum testów. Charakteryzują się mniejszą ilością „false positive’ów”. Przykładem takiego narzędzia jest OWASP ZAP.

Pomimo dużej przydatności narzędzi automatycznych, warto znać ich ograniczenia. Narzędzia te opierają się na regułach, które wraz z rozwojem technologii — m.in. powstawaniem nowych framework’ów, bibliotek wymagają aktualizacji reguł.

Oprócz tego, narzędzia automatyczne nie znają logiki działania aplikacji ani jej przeznaczenia. Nie są w stanie znaleźć błędów logicznych, których przeoczenie może mieć katastrofalne skutki w kontekście bezpieczeństwa. Z tego też powodu testy bezpieczeństwa nie powinny się opierać jedynie na narzędziach automatycznych — narzędzia te powinny stanowić wsparcie manualnych testów penetracyjnych.

Najczęstsze problemy związane z bezpieczeństwem aplikacji

Podatności — ryzyko utraty poufnych informacji

Jedną z najczęściej spotykanych podatności jest „Broken Access Control”. W uproszczeniu podatność polega na niewłaściwej weryfikacji, czy dany zasób/użytkownik powinien mieć dostęp do funkcjonalności X lub zasobu Y. Wskutek nieprawidłowości, atakujący może np. uzyskać nieodpowiednie uprawnienia, a tym samym dostęp do danych innych użytkowników.

Przykładowo — od strony klienckiej (frontendu) — prawidłowe jest, że dla użytkowników innych niż administratorzy nie są wyświetlane formularze z operacjami administracyjnymi. Jednakże po stronie serwerowej (backendowej) brakuje jakiejkolwiek weryfikacji, czy rzeczywiście użytkownik wywołujący akcję jest administratorem.

Taki typ błędu, gdy użytkownicy o niższych uprawnieniach, w wyniku nieprawidłowego uzyskania dostępu, mogą wykonywać akcje przeznaczone dla innego typu użytkowników (np. administratorów), nazywamy „vertical privilege escalation”. Z kolei, gdy dany typ użytkowników ma dostęp do np. wgrywania prywatnych plików, jednakże brakuje weryfikacji czy rzeczywiście użytkownik odwołuje się do własnego pliku — wtedy mówimy o „horizontal privilege escalation”.

Nie bez powodu podatność „Broken Access Control” znalazła się na pierwszym miejscu listy OWASP Top Ten 2021. Jest to klasa podatności, której nie da się wykryć automatycznymi narzędziami — automaty nie znają kontekstu aplikacji i nie mają wiedzy biznesowej. Nie są w stanie określić, czy funkcjonalność X powinna być dostępna dla wszystkich, czy np. tylko dla kadry HR. Albo czy plik Y powinien być dostępny dla danego użytkownika.

Tabela prezentująca listę podatności, które należy brać pod uwagę przeprowadzając testy bezpieczeństwa. Tabela porównuje listę z 2017 oraz 2021 roku
Źródło: https://owasp.org/Top10/  

Niewłaściwa separacja środowisk

Kolejnym często spotykanym problemem jest brak właściwej separacji środowisk testowych i developerskich od produkcyjnych. I o ile często dba się o bezpieczeństwo środowisk produkcyjnych, o tyle panuje powszechne przekonanie, że środowiska testowe nie muszą być aż tak ściśle zabezpieczone (z racji nietrzymania tam wrażliwych danych).

Jest to niestety błędne myślenie. Nierzadko zdarza się, że nieświadomie używane są te same sekrety, np. ten sam klucz na środowisku testowym i produkcyjnym, do weryfikacji poprawności sygnatur JWT.

W takim przypadku uzyskanie dostępu do uprzywilejowanego konta na środowisku testowym może być równoznaczne z uzyskaniem tych samych uprawnień na środowisku produkcyjnym.

Infrastruktura IT

W kontekście bezpieczeństwa nie wystarczy skupić się jedynie na warstwie aplikacji. Bezpieczeństwo całości systemu stanowi jego najsłabsze ogniwo. Nie zapominajmy więc o bezpieczeństwie infrastruktury. Czy mamy aktualną wersję webservera (Apache, nginx) bez znanych podatności? Czy nie mamy błędów konfiguracyjnych? Dla przykładu: nginx alias traversal.

Pytanie także, czy nie wystawiamy na świat zbyt wielu usług? Choćby dla przykładu wystawienie usługi JDWP (Java Debug Wire Protocol) prowadzi do nieuwierzytelnionego zdalnego wykonania kodu (Unauthenticated Remote Code Execution), co jest równoznaczne z całkowitym przejęciem systemu.

Natomiast jeżeli korzystamy z usług dostawców cloudowych (np. AWS, Azure, GCP), to również należy zadbać o bezpieczeństwo konfiguracji. O ile niebezpieczna konfiguracja bucketów AWS S3 jest już w tej chwili raczej rzadkością, tak istnieje wiele innych usług, gdzie błędy konfiguracyjne mogą prowadzić do poważnych problemów bezpieczeństwa. Takimi krytycznymi usługami są np. AWS API Gateway czy AWS Cognito.

Testy bezpieczeństwa systemów informatycznych — dlaczego warto?

Dlaczego warto przeprowadzać testy bezpieczeństwa? Jak widać, niebezpieczeństw jest dużo, a w końcu taniej jest zapobiegać niż obsługiwać skutki udanego ataku (podobnie jak taniej jest testować na bieżąco, niż czekać z testami aż do zakończenia projektu).

Działania naprawcze mogą stać się naprawdę poważnym uszczerbkiem w firmowym budżecie. Obsługa incydentu wiąże się m.in. z analizą powłamaniową, unieważnieniem sekretów (kluczy API, tokenów dostępu), wymuszeniem zmiany haseł użytkowników, jak również poinformowaniem odpowiednich instytucji rządowych o naruszeniu danych. A najgorsze, że wynikiem ataku może być ujawnienie danych klientów, co zawsze kończy się poważną utratą ich zaufania.

Innym powodem wykonywania testów bezpieczeństwa są regulacje prawne, wręcz obligujące do regularnego przeprowadzania testów. Jeżeli chcemy mieć pewność, że partner tworzący, utrzymujący czy rozwijający nasze oprogramowanie przeprowadza regularne testy bezpieczeństwa, zwracajmy uwagę np. na certyfikat ISO/IEC 27001.

Chcesz zawczasu eliminować zagrożenia i szukasz pomocy w testowaniu bezpieczeństwa swoich aplikacji?