Zespół deweloperski może przeprowadzić threat modeling funkcji w godzinę, jeśli odpowie po kolei na cztery pytania i wyjdzie ze spotkania z ticketami, a nie z dokumentem. Pytania pochodzą z Threat Modeling Manifesto: nad czym pracujemy, co może pójść nie tak, co z tym zrobimy i czy wykonaliśmy to wystarczająco dobrze. Nie potrzebujesz do tego architekta bezpieczeństwa, ponieważ ta praca nie zależy od wrodzonych zdolności jednej osoby.
Godzina w skrócie
| Minuty | Pytanie | Rezultat |
|---|---|---|
| Przed sesją | - | Jedna osoba przygotowuje szkic diagramu przepływu danych |
| 0-10 | Nad czym pracujemy | Poprawiony diagram, ponumerowane punkty wejścia |
| 10-30 | Co może pójść nie tak | Lista zagrożeń pogrupowana według kategorii STRIDE |
| 30-45 | Co z tym zrobimy | Odpowiedź na każde zagrożenie |
| 45-55 | Tickety i testy | Jeden ticket i jeden test na każde działanie ograniczające |
| 55-60 | Czy wykonaliśmy to wystarczająco dobrze | Kontrola kompletności |
Przed sesją
Wybierz jedną funkcję, a nie cały produkt. Wyszukiwanie problemów na etapie projektowania jest znacznie skuteczniejsze niż naprawianie błędów na produkcji, więc zorganizuj sesję przed rozpoczęciem implementacji.
Zaproś programistę, właściciela wymagań oraz, jeśli w grę wchodzi infrastruktura, kogoś z działu operacji. Jedna z tych osób przynosi szkic diagramu przepływu danych, wykonany w narzędziu, którego pliki zespół może później edytować.
Minuty 0-10: nad czym pracujemy
Grupa poprawia szkic. OWASP Threat Modeling Cheat Sheet wymaga czytelnego obrazu granic zaufania, przepływów danych, magazynów danych, procesów i podmiotów zewnętrznych, które często stanowią potencjalne punkty ataku. Sprawdź, czy każdy z tych elementów znalazł się na diagramie.
Jeśli część uczestników nie jest techniczna, zamiast upierać się przy notacji DFD, zbierzcie przepływy na tablicy w formie burzy mózgów.
Numeruj punkty wejścia na bieżąco, a dla warstwowych stosuj zapis major.minor (1, 1.2, 1.2.1), tak jak robi to strona procesu społeczności OWASP, i oznacz także punkty wyjścia. Komunikat o błędzie na stronie logowania może umożliwić ataki przez odpowiadający mu punkt wejścia, na przykład zbieranie nazw kont ("username not found") albo SQL injection (przez komunikaty wyjątków SQL).
Minuty 10-30: co może pójść nie tak
Przy projekcie technicznym zacznij od STRIDE. Przeprowadź każdy komponent, przepływ danych i granicę zaufania przez sześć kategorii i zapisuj, którego identyfikatora punktu wejścia dotyczy każde zagrożenie.
| Kategoria | Narusza | Przykład |
|---|---|---|
| Spoofing | Uwierzytelnianie | Skradziony token uwierzytelniający użyty do podszycia się pod użytkownika |
| Tampering | Integralność | Niezamierzone modyfikacje bazy danych za pośrednictwem aplikacji |
| Repudiation | Rozliczalność | Zmanipulowane logi maskujące wykonane działania |
| Information Disclosure | Poufność | Dane wyciągnięte z bazy kont użytkowników |
| Denial of Service | Dostępność | Użytkownik zablokowany przez wiele nieudanych prób uwierzytelnienia |
| Elevation of Privileges | Autoryzacja | JWT zmodyfikowany w celu zmiany roli |
W przypadku reguły biznesowej dodaj misuse cases: działania wykonywane w złej kolejności, wielokrotnie, równolegle lub w celu uzyskania niezamierzonego efektu. Dla jednego wieloetapowego celu atakującego użyj drzewa ataku. Nie dokładaj technik tylko po to, by wyglądać na dokładnego; wyjaśnij, dlaczego każda z nich pasuje i czego nie obejmuje.
Prawdopodobieństwo razy wpływ brzmi porządnie, ale oba parametry trudno oszacować, a iloczyn pomija koszt poprawki. W godzinę wystarczy przybliżona ocena wysoki, średni lub niski dla każdego zagrożenia.
Przykład z praktyki: reset hasła
Weźmy reset hasła. Diagram pokazuje przeglądarkę, aplikację webową, bazę użytkowników i usługę poczty, a między internetem i aplikacją przebiega granica zaufania. Żądanie resetu to punkt wejścia 3, a link przesłany e-mailem to 3.1 (identyfikatory poglądowe).
Grupa znajduje cztery zagrożenia. Link resetujący działa dla kogoś innego niż właściciel konta (spoofing). Komunikat "no account with that address" ujawnia, kto jest zarejestrowany (information disclosure). Zdarzenia resetu nie są logowane (repudiation). Ktoś wywołuje wielokrotne resety wobec ofiary (denial of service).
Minuty 30-45: co z tym zrobimy
Każde zagrożenie dostaje jedną z czterech odpowiedzi:
- Ogranicz (mitigate): zmniejsz prawdopodobieństwo, że zagrożenie się zmaterializuje.
- Wyeliminuj (eliminate): usuń funkcję lub komponent, który je powoduje.
- Przenieś (transfer): przenieś odpowiedzialność umowną lub finansową na inną stronę.
- Zaakceptuj (accept): nie rób nic, ponieważ pozostałe opcje nie mieszczą się w ograniczeniach biznesowych.
Przeniesienie samo w sobie nie zmniejsza prawdopodobieństwa ani szkody, więc zapisz, kto odpowiada za pozostałe zabezpieczenia i ryzyko rezydualne. W przypadku zaakceptowanych zagrożeń odnotuj, kto zaakceptował ryzyko i dlaczego.
Minuty 45-55: tickety i testy
Zamień każde uzgodnione działanie ograniczające w wymaganie, które programista może od razu podjąć. Wystarczy jeden wiersz na zagrożenie:
| ID zagrożenia | STRIDE | Ticket | Test |
|---|---|---|---|
| 3.1-S | Spoofing | Spraw, aby linki resetujące były jednorazowe i krótko ważne | Użyty lub wygasły link zostaje odrzucony |
| 3-I | Information Disclosure | Zwracaj jedną, ogólną odpowiedź dla każdego adresu | Znany i nieznany adres dają identyczne odpowiedzi |
| 3-R | Repudiation | Loguj każde żądanie resetu | Próba resetu pojawia się w logu |
Kolumna z testami sprawia, że model to coś więcej niż diagram. Każde działanie ograniczające potrzebuje sprawdzenia, które kończy się niepowodzeniem, gdy zabezpieczenia brakuje. Abuse cases przekładają się wprost na testy: powtórz żądanie, wyślij kroki w złej kolejności, wyślij dwa żądania naraz. Umieść tickety w backlogu samej funkcji i dodaj identyfikator zagrożenia do tytułu.
Minuty 55-60: czy wykonaliśmy to wystarczająco dobrze
Zacznij od prostej kontroli: czy istnieją zapisy pokazujące diagram, listę zagrożeń i listę zabezpieczeń? Jeśli któregoś brakuje, sesja nie jest zakończona. Potwierdź, że każde zagrożenie ma odpowiedź, że każde działanie ograniczające mówi, jak zespół je wdroży, oraz że przy zaakceptowanych ryzykach zapisano uzasadnienie.
Następnie utrzymuj model przy życiu. Aktualizuj go razem z systemem, a gdy projekt się zmienia, powtarzaj tylko te części, których zmiana dotyczy.
Od czego zacząć
- Wybierz jedną nadchodzącą funkcję i zarezerwuj godzinę z programistą, właścicielem wymagań i kimś z działu operacji.
- Poproś jedną osobę o przygotowanie szkicu diagramu przepływu danych z zaznaczonymi granicami zaufania. Grupa poprawia go i numeruje punkty wejścia w pierwszych dziesięciu minutach.
- Przez 20 minut przeprowadź STRIDE dla każdego komponentu i przepływu, zapisując przy każdym zagrożeniu identyfikator dotkniętego punktu wejścia.
- Przypisz odpowiedź do każdego zagrożenia, zapisz, kto odpowiada za zaakceptowane lub przeniesione ryzyko, a następnie utwórz jeden ticket i jeden test na każde działanie ograniczające.
- Przechowuj diagram, listę zagrożeń i listę zabezpieczeń razem z dokumentacją funkcji. Jeśli chcesz uzyskać zewnętrzne spojrzenie na pierwszy model, nasza usługa konsultingowa może go zweryfikować, a zapisane zagrożenia dobrze posłużą jako zakres późniejszego testu penetracyjnego.
