Bezpieczeństwo systemów, które umożliwiają dokonywanie zakupów oraz przetwarzają dane osobowe, ma kluczowe znaczenie. Włamania mogą prowadzić do oszustw lub kradzieży danych, których skutki ciężko będzie przewidzieć.
Wykonanie dogłębnych testów bezpieczeństwa aplikacji wymaga dużej wiedzy oraz doświadczenia. Jeśli system jest bardzo skomplikowany i zawiera wiele dedykowanych (pisanych specjalnie dla naszego biznesu) funkcji – testy mogą być długotrwałe i drogie.

Niezależnie od tego, czy sami rozwijamy oprogramowanie, czy zlecamy jego wykonanie do firmy zewnętrznej, warto znaleźć specjalistę (lub firmę) profesjonalnie audytującego bezpieczeństwo i poprosić go o konsultacje.
Podatność naszej aplikacji na najpopularniejsze ataki możemy przetestować w prosty sposób, za pomocą bezpłatnych narzędzi. Te pracują w modelu black box (z ang. czarna skrzynka). Nie analizują sposobu wykonania aplikacji. Automatycznie lub pół-automatycznie „atakują” za pomocą spreparowanych, potencjalnie niebezpiecznych danych i weryfikują odpowiedzi systemu.

Przykładem takiego narzędzia jest Skipfish. Przeszukuje on serwis pod kątem podatności na ataki z zewnątrz.

Skipfish do swojego działania wykorzystuje heurystykę. Automatycznie generuje różnego rodzaju słowniki, uzupełnia formularze na stronach internetowych oraz wykorzystuje różne metody ataków do sprawdzenia potencjalnych luk na stronie.
Oprócz wykonania testów automatycznych warto stosować analizę kodu źródłowego (z ang. white box testing). Analiza kodu źródłowego pozwala na ocenę użycia dobrych praktyk (kodowania danych i innych) a przez to wykluczenie dużej części ataków. W taki sposób koniecznie powinny być audytuowane systemy które przetwarzają transakcje lub wykonują operacje finansowe . Niestety testy kodu źródłowego są praktycznie niemożliwe do zautomatyzowania, a co za tym idzie, ich wykonywanie jest dość kosztowne.

OWASP TOP 10

Przy każdym projekcie warto też przejść przez checklistę przygotowaną przez OWASP (Open Web Application Security Project).
Lista zawiera 10 najczęściej popełnianych błędów bezpieczeństwa spotykanych w web-aplikacjach. Podatności są pogrupowane w główne kategorie oraz posegregowane w kolejności od najczęściej występujących. Pomimo iż ostatnia aktualizacja listy miała miejsce w 2013 roku, jest ona nadal aktualna. Porównując z ostatnią aktualizacją (2010 r.) pierwsze 4 pozycje są identyczne, zmieniła się tylko ich kolejność.

Najczęściej występującym błędem w aplikacjach jest podatność typu Injection: “błędy wstrzyknięcia”. Zaliczamy do niej wszelkie próby zmiany zachowania systemu lub interpretera języka. Atak polega na odpowiednim spreparowaniu danych trafiających do systemu jako części zapytania lub polecenia. Złe obchodzenie z danymi przychodzącymi z zewnątrz (brak odpowiedniego filtrowania) może doprowadzić do wykonanania obcych działań (wykonanie kodu przesłanego przez atakującego – hakera). Uruchomienie takiego programu/polecenia może ułatwić dostęp do poufnych informacji lub wykonania nieautoryzowanych działań w systemie.

Drugą powszechnie wstępującą podatnością jest możliwość wywoływania skryptów między-serwisowych (XSS –cross site scripting). Serwis posiadający taką lukę pozwala na wywoływanie skryptów lub kodu HTML w przeglądarce ofiary (zupełnie odwrotnie jak w przypadku podatności typu injection gdzie kod był wykonywany na serwerze). Taki skrypt może przechwycić sesje użytkownika i wysłać dane o niej do atakującego, podmienić zawartość serwisu lub przekierować użytkownika na stronę zawierającą złośliwe skrypty lub oprogramowanie.

Trzecim najczęściej spotykanym uchybieniem jest nieodpowiednia/niepoprawna obsługa uwierzytelnienia i sesji. Przez niedopatrzenie programisty w bardzo prosty sposób może przejść do przechwycenia sesji użytkownika. Najprostszym przykładem jest proste przekazanie osobie trzeciej linka do zasobu strony dostępnego dopiero po zalogowaniu. W takim wypadku przy braku odpowiednich zabezpieczeń nastąpi zalogowanie do sesji użytkownika udostępniającego link.

W Divante lista TOP 10 OWASP w lekko uproszczonej formie jest jedną z checklist, którą musi spełniać system przed przystąpieniem do wdrożenia.

Narzędziem przydatnym do znajdowania takich podatności jest program ZAP (Zed Attack Proxy) tworzony przez fundacje OWASP. Działa na zasadzie serwera proxy, który w tle analizuje treści wymieniane pomiędzy przeglądarką a serwerem szukając podatności. Oferuje on też tak jak w przypadku SkipFisha automatyczne skanowanie oraz ataki słownikowe, które mogą przynieść bardzo zaskakujące wyniki, np. ujawnienie plików w tzw. głębokim ukryciu.
Należy jednak pamiętać, że testy wykonywane przez automatyczne skanery to tylko uzupełnienie zadań wykonywanych przez pentestera.
Korzystanie z systemów które są gotowe (open source, rozwiązania dedykowane) pozwala skrócić czas poświęcany na testy. Otrzymujemy też bezpłatne łatki w razie wykrycia problemów. Warto przemyśleć taką strategię przy planowaniu wdrożenia.

Testy obsługi sytuacji wyjątkowych (error handling tests)

Testy sytuacji wyjątkowych sprawdzają jak system reaguje na nieprawidłowe dane podane przez użytkownika, niepoprawne adresy URL, braki autoryzacji, problemy sieciowe (np. problemy z połączeniem do serwera bazy danych).

Można przyjąć za pewne zaistnienie sytuacji wyjątkowych – ale odłożone w bliżej nieokreślonym czasie. Warto wiedzieć, jaki komunikat zobaczą nasi użytkownicy gdy podadzą błędne dane. Jeśli zawiedzie baza danych – czy będzie można przywrócić ją do działania? Czy użytkownicy zostaną poinformowani o problemie w odpowiedni sposób? Plansze z informacją o przerwie konserwacyjnej, czy przełączenie użytkownika na zapasowy serwer to tylko niektóre z działań jakie można podjąć w przypadku awarii.
Najgorsze i najmniej profesjonalne jest ignorowanie sytuacji wyjątkowych i zdanie się na automatyczne błędy (często w języku angielskim) pozostawiające zdezorientowanego użytkownika bez wsparcia.

W Divante, w celu uniknięcia takich sytuacji powołaliśmy Grupę Uderzeniową – S.W.A.T Divante. Grupa liczy 3-4 osoby i udział w niej jest dobrowolny. Osoby należące do grupy maja za zadanie zachowanie SLA na utrzymanie serwisów które obsługujemy. Za wszelką cenę i wszystkimi dostępnymi i legalnymi sposobami. Grupa ma dostęp do administratorów systemowych oraz zewnetrznej firmy konsultingowej. S.W.A.T Divante stanowi pierwszą linię obsługi błędów – reaguje, wykonując wszelkie możliwe zadania, aby niezależnie od pory dnia/nocy rozwiązać problem w jak najkrótszym czasie.

Testy automatyczne – selenium

W poprzednim wpisie wspominałem o konieczności wykonywania testów funkcjonalnych. Jednak sprawdzanie za każdym razem tych samych ścieżek może być frustrujące zarówno dla testerów jak i deweloperów ze względu na monotonie i powtarzalność. Może to prowadzić do bardziej pobieżnego sprawdzenia serwisu lub nie przetestowania wszystkich ścieżek krytycznych. Z pomocą przychodzą tutaj testy automatyczne.
W Divante już na wczesnym etapie wdrożenia projektujemy i programujemy testy automatyczne. Odciąża to testerów oraz programistów, gdyż to automaty sprawdzają wszystkie podstawowe ścieżki w systemie, natomiast specjaliści mogą tym czasie skupić się na nowych funkcjach.
Jako, że w Divante zajmujemy się głównie aplikacjami webowymi słusznym kierunkiem rozwoju były testy automatyczne napisane w selenium. Upublicznione w 2007 roku na licencji Apache 2.0, narzędzie stworzone przez Jasona Hugginsa szybko zyskało rzeszę fanów i stało się jednym z głównych instrumentów używanych w testowaniu aplikacji internetowych.

Składa się z 3 głównych komponentów:
– selenium IDE (integrated development environment) – wtyczka do przeglądarki FireFox
– selenium RC (remote control) – umożliwia uruchamianie testów napisanych w selense pod dowolną przeglądarką, nazywane również selenium 1
– selenium WebDriver – rozszerzona wersja selenium RC, pozwala na programowanie testów w popularnych językach programowania ( Java, C#, Python, Ruby, Perl, PHP), zwane też selenium 2.0.

Aby zacząć pisać testy w selenium (IDE) nie trzeba być programistą. Wystarczy przejść dany scenariusz z włączonym rozszerzeniem. Dla nieskomplikowanych akcji to wystarczy. Niestety takie testy ciężko jest potem dostosowywać do zmian w aplikacji. Dlatego warto od samego początku przenieść testy na wyższy poziom i programować je z użyciem WebDrivera.
Takie testy mogą być połączone z systemem do integracji ciągłej (continuous integration) pozwalają na monitoring aplikacji w taki sam sposób, w jaki robią to jej użytkownicy. Jest to dodatkowy środek do zapewnienia najwyższej jakości SLA.

Continuous integration – Jenkins

Ciągła integracja to nie tylko dostarczanie „świeżych” wydań oraz testy selenium. Dzięki systemowi ciągłej integracji możemy dowiadywać się w szybki sposób o kondycji i bezpieczeństwie aplikacji. Przy dobrej konfiguracji wszystkich narzędzi można powiedzieć, że w dużej mierze aplikacja (albo przynajmniej jej najbardziej newralgiczne obszary) testuje się sama. CI przy każdej nowej paczce kodu dostarczonego przez programistę sprawdza poprawność składniową i jakość kodu (wykrywanie powtórzeń w kodzie, generowanie dokumentacji). Nie ma przeszkód aby cyklicznie np. w późnych godzinach nocnych testować wydajność aplikacji sprawdzając tym samym poprawność kodu. Każde odchylenie od normy jest odpowiednio alterowane poprzez wysłanie wiadomości email do zespołu lub poprzez komunikator tekstowy (HipChat, Slack, Hangout). Dobrym zwyczajem jest też zastosowanie CI do wykonywania testów regresyjnych.

Testy przywracania systemu (recovery tests)

Kopie zapasowe systemu – które zazwyczaj są wykonywane – to bardzo ważny element wpływający na ciągłość działania. Dzięki nim możemy podźwignąć się po nietypowych sytuacjach – takich jak awaria systemu czy atak na niego.
Pewne jest to, że tworzymy kopie zapasowe. Ale musimy mieć jednocześnie pewność, czy kopie te dają się odtworzyć, czy nie zawierają błędów lub czy korzystanie z nich jest nadmiernie trudne i czasochłonne?

Na kopie składają się zazwyczaj:
– kopie bazy danych systemu
– kopie plików aplikacji oraz plików wgrywanych przez użytkowników
– kopie konfiguracji i skryptów służących do uruchomienia i opieki nad systemem.

Jeśli aplikacja jest rozbudowana, korzysta z kilku serwerów, to odtworzenie jej stanu z kopii zapasowej może być procesem trudnym. W przypadku systemów transakcyjnych żadne zamówienia nie powinny się zgubić, skomplikowana aplikacja to także skomplikowane pliki konfiguracyjne a nawet cała procedura uruchamiania systemu.

Dlatego warto testować odtwarzanie systemu?

Z jednej strony testy pozwalają nam sprawdzić czy wykonywane kopie zapasowe są kompletne i poprawne. Z drugiej strony możemy sprawdzić jak długo trwa cała procedura.

Testy obciążeniowe

Aplikacje tworzone są do realizacji pewnych założeń biznesowych. Inwestycja w tworzenie systemu musi się zwrócić, a zwrot taki jest zazwyczaj uzależniony od obsługi określonej liczby użytkowników i transakcji.
Aby zminimalizować koszty i czasochłonność poświęcone na testy – możemy zweryfikować wartości maksymalne jakie obsłuży system, korzystając z automatycznych narzędzi testujących. Ich działanie przypomina automaty testujące bezpieczeństwo połączone z automatycznymi testami behawioralnymi.
Innymi słowy obsługa zakładanej liczby jednoczesnych użytkowników zostaje w prosty sposób przetestowana. Narzędzie jakie możemy zastosować to jMeter.

Ograniczeniem programu jest wydajność urządzenia, na którym jest uruchamiane oraz przepustowość łącza. Bez większych przeszkód jesteśmy w stanie wygenerować ruch rzędu nawet 10 000 jednoczesnych użytkowników na stronie lub równie dużo unikalnych wejść. Ofiarą ataku może być system jako całość (wejścia na pojedyncze strony, przechodzenie konkretnych ścieżek, składanie zamówień) jak i bezpośrednio jego elementy składowe (serwer aplikacyjny, mediów czy baza danych). Wykonując takie testy w szybki i łatwy sposób możemy dostrajać maszyny do jak najwydajniejszego działania. Pokazują one jak zachowa się system w przypadku zbyt dużego obciążenia (przeciążenia) lub co się wydarzy przy długotrwałym dużym obciążeniu (np. wyprzedaż). W ten sposób możemy też poznać maksymalne fizyczne możliwości sprzętu.
Testy obciążeniowe powinny być wykonywane w środowisku jak najbardziej zbliżonym do produkcyjnego lub produkcyjnym przed wdrożeniem. Chcemy przecież poznać rzeczywiste możliwości systemu, jego słabe strony i „wąskie gardła”.
Oprócz testów przed uruchomieniem ważny jest monitoring parametrów serwera. Monitoring obciążenia procesora, zużycia pamięci, wykorzystania dysku twardego pozwoli nam wcześniej zauważyć problemy.

Należy pamiętać, że nie wolno wykonywać ataków na strony/aplikacje na które nie mamy pisemnego pozwolenia. Dotyczy to zarówno testów wydajnościowych jak i bezpieczeństwa. Za niestosowanie się do tej zasady kodeks karny przewiduje karę grzywny, ograniczenia wolności albo pozbawienia wolności do lat 2.

Więcej o ty, jak dbamy o najwyższą jakość w Divante w poprzednich artykułach o poprawnym i bezpiecznym testowaniu i prowadzeniu przydatnej dokumentacji.

Chcesz poprawić jakość Twojego e-biznesu? Napisz do nas.