Wrócę do tematu, który poruszałem ponad rok temu we wpisie Testy penetracyjne: kiedy testować?, przy czym tym razem z nieco innej perspektywy, bardziej od strony tworzenia aplikacji.
Test early, test often
Po pierwsze warto zastanowić się, jaka wersja systemu jest tworzona. Chodzi o to, że czasami rozpoczynając pracę nad systemem, podchodzi się do tematu bardzo optymistycznie, w szczególności odnośnie jego zakresu, który powinien być zrealizowany w określonym czasie przy określonych środkach. Później następuje bolesna weryfikacja założeń, zderzenie z brutalną rzeczywistością. W efekcie parametry czasu oraz kosztów rosną, natomiast zakres się zmniejsza. Część funkcji zostaje przesuniętych do kolejnej wersji, albo są kończone "na siłę", przy czym ich szeroko pojęta jakość drastycznie spada. W skrajnych przypadkach niektórych funkcji najnormalniej na świecie nie da się używać (...), a na kolejną wersję produktu trzeba znów czekać jak na Chinese Democracy. Tak to jest, jak się chce stworzyć aplikację w wersji 3.0, a "pół roku" później już w wersji 7.5.
Testowanie produktu, który zamiast jasnego planu rozwoju ma rozmytą wizję, jest trudne. Ciężko przewidzieć co, jak i kiedy zostanie "puszczone na produkcję", a co nigdy nie doczeka się używalnej wersji. Przy chaosie, który pojawia się w takich przypadkach, zupełnie normalne jest, że moduł zgłoszony do testów nie działa (funkcjonalnie), albo nawet w trakcie samych testów przechodzi istotne zmiany... Potem przychodzi etap usuwania błędów, które (być może) psują coś w funkcjonalności produktu, w związku z czym przychodzi nowa łatka, która albo ponownie wprowadza starą podatność, albo nową lepszą. Gdy w końcu uda się dotrzeć do szczęśliwego końca, okazuje się, że jednak koniec wcale nie jest szczęśliwy, bo wizja się zmieniła, i trzeba wprowadzić "małą" zmianę, która efektywnie powoduje, że wszystkie testy (funkcjonalne, wydajnościowe, bezpieczeństwa), trzeba zacząć od początku.
Powyższa sytuacja jest może nieco przejaskrawiona, ale aż tak bardzo nie odbiega jednak od zwykłej, szarej rzeczywistości. Miałem okazję takie sytuacje śledzić z różnych perspektyw, pracownika firmy tworzącej oprogramowanie (choć zajmowałem się czym innym, a na temat swojego głęboko osadzonego urazu do pojęcia burza mózgów może kiedyś napiszę), pracownika korporacji zamawiającej duże, dedykowane (albo raczej dostosowywane) aplikacje i systemy, czy wreszcie z pozycji (pen)testera.
Osobiście uważam, że lepszym podejściem przy tworzeniu aplikacji jest stawianie małych kroczków. Oczywiście, można sobie stawiać ambitne cele (jest to nawet wskazane), ale trzeba jeszcze realistycznie patrzeć na możliwości ich realizacji. Co więcej, ale to już kwestia mniej techniczna, warto obserwować co o produkcie myślą klienci, nawet jeśli dostęp do niego ma jedynie ograniczona grupa użytkowników. Feedback z ich strony może być na prawdę bardzo przydatny i w istotny sposób wpłynąć na końcowy produkt, który dzięki temu może być lepiej dostosowany do potrzeb użytkowników (klientów).
Gdzie w takim przypadku umieścić testy bezpieczeństwa? Jeśli testy są postrzegane jako pewna "jednorazowa" (mająca miejsce w określonym czasie, nawet jeśli są one okresowe) aktywność, to należy testować taką wersję systemu, z jakiej korzystać będą użytkownicy/klienci, jaka będzie wykorzystywana na produkcji. W takim przypadku przed rozpoczęciem testów aplikacja powinna posiadać już wszystkie przewidziane (w tej wersji) funkcje, być przetestowana funkcjonalnie i działać. Po testach nie powinny być wprowadzane żadne nowe zmiany, bo każda taka zmiana może wprowadzić podatności. Nawet w tym przypadku i przy takich wymaganiach nie koniecznie oznacza to odkładanie testów na ostatnią chwilę, bo można testować poszczególne moduły, gdy są do tego gotowe. Gorzej, jeśli wszystkie moduły oddawane są dopiero na samym końcu...
Dobrze jest jednak postrzegać (w)budowanie bezpieczeństwa jako proces, którego elementem są testy bezpieczeństwa. Testy, które służą nie tyle identyfikacji podatności, co weryfikacji zastosowania środków zaradczych. Przy takim podejściu "szybkie testy" wczesnych wersji aplikacji mają sens, pod warunkiem, że ich rezultaty nie trafiają w próżnię. Chodzi tu przede wszystkim o przepływ informacji na linii (pen)testerzy - programiści, przy czym pod pojęciem programistów należy (wyjątkowo) rozumieć również architektów aplikacji, zwłaszcza, jeśli te role są wyraźnie oddzielone.
Głównym zyskiem, który widzę w takim podejściu, jest możliwość szybkiej identyfikacji problemów związanych z bezpieczeństwem aplikacji, które mogą wynikać z różnych przyczyn, na przykład z błędnych założeń, nieodpowiedniej architektury, braku stosowania odpowiednich środków zaradczych (countermeasures), stosowania nieodpowiednich praktyk programistycznych, czy wreszcie wynikających ze zwykłych błędów ludzkich lub braku wiedzy.
Im wcześniej problem zostanie zidentyfikowany, tym lepiej i tym tańsze jest jego usunięcie. Co więcej istnieje duże prawdopodobieństwo, że raz znalezione błędy nie będą się powtarzać, bo:
- wyeliminowana zostanie ich przyczyna (np. zwiększy się wiedza zespołu tworzącego aplikację),
- zostaną stworzone odpowiednie testy wychwytujące dany problem (bo można tak zrobić, przynajmniej w części przypadków),
Wszystko to jest prawdą wyłącznie wtedy, gdy testów i kwestii bezpieczeństwa nie traktuje się jak piątego koła u wozu. Dokładnie tak samo, jak wówczas, gdy udostępnienie wersji beta, technology preview czy RC produktu nie ma sensu, jeśli nie zamierza się słuchać głosu użytkowników (testerów) i uwzględniać go w dalszych pracach. Trzeba słuchać testerów i korzystać z tego, co mówią. Zresztą zamiast nazywać ich (pen)testerami albo (czego nie lubię) Audytorami (koniecznie przez duże A), może określić ich (nas) jako konsultantów. Niby niewiele, ale zmienia to trochę sposób, w jaki testy bezpieczeństwa są postrzegane i jak traktowane są ich wyniki. To, co mnie męczy, to brak przełożenia mojej pracy na zmianę sposobu tworzenia (kolejnych) aplikacji, pisałem zresztą już o depresji pentestera. Zresztą, jak się okazuje, nie tylko ja miewam takie refleksje.
Podejście częstych i wczesnych testów bezpieczeństwa (lub raczej weryfikacji mechanizmów bezpieczeństwa) jest możliwe do zastosowania zarówno przez producentów oprogramowania, którzy dostrzegają potrzebę poprawy bezpieczeństwa swoich produktów, jak i przez zamawiających, dla których bezpieczeństwo otrzymywanego systemu jest istotne. Swoją drogą ciekawym tematem może być kwestia co może zrobić zamawiający, gdy widzi, że dostawca tworzy produkt, który "nie do końca" spełnia jego oczekiwania (bezpieczeństwo, ogólna jakość, wydajność, ergonomia). Macie w tym temacie jakieś przemyślenia?
Jeśli tego nie zrobimy przed rozpoczęciem pracy to potem niestety możemy zostać na lodzie z aplikacją nadającą się do wyrzucenia - chyba, że zamówimy u dostawcy poprawkę i zapłacimy za nią z własnej kieszeni...
Widziałem już umowy gdzie wykonawca zastrzegał sobie, że nikt nie ma prawa bez jego zgody przeprowadzać żadnych testów aplikacji. Na ile taka klauzula jest to zgodna z prawem nie podejmuję się wypowiadać - ale ładnie to pokazuje podejście niektórych dostawców.
Mnie ciekawi temat rozwiązywania/odstępowania od umów/kontraktów. Oczywiście odstąpić można zawsze, chodzi mi tu o takie odstąpienie, przy którym wina będzie po właściwej stronie.
A do kategorii absurdów można zaliczyć testy akceptacyjne wykonywane przez pracowników dostawcy systemu albo testy bezpieczeństwa wykonywane przez zewnętrznych testerów ALE rękami dostawcy.
Paweł, wydaje mi się, że to o czym piszesz to SDLC, który często (w tej brutalnej/złej rzeczywistości) składa się z przykładowo następujących kroków:
1) biznes: potrzebujemy system X
2) it: ok, 40 dni (tak na oko)
3) biznes: system ma robić to, to, to i jeszcze to
4) it: :o ok!
...
x) it: system jest dostępny pod tym adresem
x+1) biznes: ale tutaj prawie nic nie działa...
x+2) it: a co chcieliście w 40 dni?
x+3) biznes: system na być gotowy na produkcji za 5 dni!
...
y) it: (pen)testerze, możesz przetestować system X
y+1) (pen)tester: ok, na kiedy, co to za system, ...
y+2) it: jutro startujemy, a opis systemu to ma biznes, my to tylko napisaliśmy, oczekujemy OKejki, tylko szybko bo zabijasz biznes!
Niestety to nie są praktyki z jednej czy dwóch firm. Tak i podobnie jest często. I jak tu nie stać się wrogiem publicznym?
Nie generalizując: nie wszędzie jest (aż) tak (źle)