Było już o technikach wykorzystywanych na poziomie projektu i kodu oraz o wpływie języka programowania na bezpieczeństwo. Dzisiaj odpowiemy sobie na pytanie w jaki sposób zarządzać ryzykiem, wykrywać potencjalnie niebezpieczne zachowania i dodawać odpowiednie środki zaradcze do projektu.
Naiwne podejście do bezpieczeństwa
Najprostszym sposobem jaki przychodzi do głowy, kiedy myślimy o zapewnieniu bezpieczeństwa systemu jest zapewnienie najpierw funkcjonalności, a dopiero później dodanie bezpieczeństwa. Niestety to nie zadziała. Niektóre środki bezpieczeństwa wymagają na przykład specjalnych rozwiązań w hardwarze, czy architekturze systemu. Poza tym takie odkładanie na później zawsze kończy się tak samo – zajmuje więcej czasu, a i tak nie jest zrobione dobrze.
Kolejnym narzucającym się podejściem jest złożenie bezpiecznego systemu z poszczególnych bezpiecznych elementów. Niestety to również nie zda egzaminu. System może składać się z samych bezpiecznych komponentów, ale interakcje między nimi sprawiają, iż jako całość system bezpieczny nie jest. Na szczęście działa to też w drugą stronę – nie musimy zapewniać bezpieczeństwa każdego elementu z osobna. Wystarczy jeżeli problemy jednego bloku niweluje inny.
Jedynym podejściem, które może nam zapewnić sukces jest branie pod uwagę bezpieczeństwa już od najwcześniejszych faz projektu. Pomóc nam w tym może wykonywanie formalnej analizy ryzyka.
Jak wygląda analiza ryzyka?
Wykonanie formalnej analizy ryzyka nie jest wcale takie skomplikowane. Wymaga jednak dużej wiedzy technicznej osób biorących w niej udział, aby mogły poprawnie określić możliwe defekty i ryzyko z nimi związane. Podczas takiej analizy wypisujemy możliwe defekty systemu, a następnie oceniamy jakie mogą mieć skutki. Bieżemy pod uwagę dwa kryteria:
- Krytyczność – jak poważne mogą być konsekwencje.
- Częstotliwość – jak często mogą się wydarzyć.
Kombinacja tych dwóch kryteriów pozwala nam umiejscowić konkretny defekt na macierzy ryzyka.
Dla każdego poziomu bezpieczeństwa mamy zdefiniowany możliwy poziom ryzyka na macierzy. o ile defekt przekracza ten poziom, należy wprowadzić do systemu środki zaradcze, które zmniejszą krytyczność albo częstotliwość występowania defektu do akceptowalnego poziomu.
Analizę ryzyka powinniśmy wykonywać już od wczesnych faz projektu. Jesteśmy w stanie ją rozpocząć już po zebraniu wymagań. Dzięki temu będziemy w stanie sformułować również wymagania bezpieczeństwa. W kolejnych fazach V-modelu można doprecyzowywać szczegóły wskazanych defektów, albo znajdować nowe. Na każdym następnym poziomie mamy lepszy obraz systemu i możemy precyzyjniej określać ryzyko związane z konkretnymi defektami. Kroki podjęte w celu zmniejszenia ryzyka mogą być realizowane w różnych fazach V-modelu – architekturze, designie, kodzie, testach.
Ciągi przyczynowo-skutkowe i podejście systemowe
Możliwe wypadki często rozpatruje się jako ciąg przyczynowo-skutkowy, gdzie każdy element ma określone ryzyko zajścia. Takie podejście jest krytykowane przez Nancy Leveson(która jest najbardziej uznanym ekspertem z dziedziny bezpieczeństwa systemów) w książce Engineering a Safer World (która jest możliwa do pobrania za darmo). Model przyczynowo skutkowy jest zbyt uproszczony i nie artykułuje odpowiednio wielu ważnych aspektów, wpływów socjologicznych, cięcia kosztów, dawniejszych decyzji i ich interakcji między sobą. Dlatego zgodnie z tym modelem wypadki są często tłumaczone jako jednoczesne zajście wielu czynników o bardzo małym prawdopodobieńśtwie. Model taki często bardziej służy wskazywaniu winnych niż dochodzeniu do istoty problemu i wyciąganiu wniosków.
Nancy Leveson zamiast tego proponuje rozpatrywanie systemu jako układ dynamiczny ze sprzężeniem zwrotnym na który działają jednocześnie różne siły (czyli np. ograniczenia i zabezpieczenia, procedury). System jest dynamiczny, czyli zmienia się w czasie. Do mnie wytłumaczenie jakiegokolwiek problemu w oparciu o pętlę sprzężenia zwrotnego zawsze będzie przemawiać. W końcu kończyłem automatykę.
Jak obniżać ryzyko?
Obniżanie ryzyka możemy realizować na poziomie:
- Hardware’u,
- Software’u,
- Ludzi i procedur.
Kolejność powyższych punktów nie jest przypadkowa. HW jest najbardziej powtarzalny i niezawodny, poza tym psuje się w przewidywalny sposób. Software jest dużo bardziej skomplikowany dzięki czemu z jednej strony pozwala kontrolować rzeczy trudne do realizacji czysto hardware’owej, ale z drugiej strony dużo łatwiej o błędne działanie, którego dodatkowo nie da się łatwo przewidzieć. o ile HW i SW nie wystarczą do zapewnienia bezpieczeństwa – dopiero wtedy powinniśmy angażować ludzi i procedury. Nie możemy jednak iść na łatwiznę i zrzucać na ich barki zbyt dużej odpowiedzialności. Posłużę się tutaj cytatem z wspomnianej wcześniej Nancy Leveson:
„Insisting that operators always follow procedures does not guarantee safety, altough it does usually guarantee that there is someone to blame – either for following the procedures or not following them – when things go wrong.”
Myślenie o możliwych błędach i sposobach zapobiegania im od najwcześniejszych faz projektu nie jest praktykowane w większości projektów zwykłych systemów, a mogłoby być wartościowe. Branża wręcz idzie w odwrotnym kierunku kierując się raczej ideą „Fail early, fail often”. A szkoda, bo wielu błędów na pewno można by uniknąć stosując analizę ryzyka choćby w bardzo okrojonej formie.