Zamieńmy Twój pomysł w przejrzysty plan

Typ projektu

Dziękujemy!

Odpowiemy w ciągu 24 godzin.

“Nasz zespół potrafi przekształcić każdy pomysł w rozwijający się produkt”

Taras Gopko

CEO i założyciel Appricotsoft

bezpłatne rozwiązania w zakresie bezpieczeństwa od samego początku

Bezpieczeństwo od samego początku: decyzje, które można podjąć bez żadnych kosztów przed rozpoczęciem tworzenia

„Bezpieczeństwo od samego początku” nie jest ramą, którą się wdraża. To krótka lista decyzji, które podejmuje się przed pierwszym wydaniem, kiedy zmiana zdania nadal nic nie kosztuje. Cała istota tkwi w tej asymetrii: decyzja o rezygnacji z gromadzenia danych w danym polu nie wiąże się z żadnymi kosztami przed uruchomieniem, a po nim wymaga migracji oraz wymuszonej aktualizacji klienta. Niniejszy artykuł stanowi właśnie tę listę, uporządkowaną zgodnie z kolejnością, w jakiej zespół ds. wdrożeń faktycznie się z nią zapoznaje.

Istota pytania

Większość zespołów traktuje bezpieczeństwo jako oddzielny etap: najpierw tworzy się produkt, następnie wzmacnia się jego zabezpieczenia, a na końcu spisuje się wymagania dotyczące bezpieczeństwa na potrzeby kwestionariusza dla klienta. Taka kolejność sprawdza się w przypadku elementów, które nakładają się na to, co już stworzyłeś — skanowanie zależności, testy penetracyjne, ograniczenia szybkości. Nie sprawdza się jednak w przypadku wszystkiego, co dotyczy modelu danych, modelu uprawnień lub ustawień domyślnych, ponieważ są to elementy nośne. Gdy prawdziwi użytkownicy zaczną na nich polegać, nie podejmujesz już decyzji, lecz przeprowadzasz migrację.

A więc praktyczna definicja: bezpieczeństwo od samego początku oznacza podjęcie decyzji o charakterze strukturalnie nieodwracalnym na samym początku projektu, a te, których cofnięcie nie wiąże się z dużymi kosztami, pozostawić na później. Żadnych certyfikatów, żadnego dedykowanego inżyniera ds. bezpieczeństwa, żadnych nowych dokumentów proceduralnych — wystarczy po prostu wiedzieć, które decyzje są które. Większość z tych decyzji zmniejsza powierzchnię ataku poprzez usuwanie pewnych elementów, a nie poprzez nakładanie na nie dodatkowych środków kontroli.

Oto podział, który ma znaczenie:

DecyzjaKoszt przed pierwszym wydaniemKoszt po uwzględnieniu rzeczywistych użytkowników
Brak pobierania pola danychZero — jedna wiersz w schemacieMigracja, uzupełnianie danych, aktualizacja klienta, wnioski o usunięcie
Gdzie przechowywane są tokeny i klucze tajneZero — wybierz miejsce tylko razOdkrywanie każdej tajemnicy, która dotknęła niewłaściwego miejsca
Ustawienia domyślne dla danych współdzielonychZero — zmiana wartości logicznejUżytkownicy polegają na domyślnym ustawieniu „otwarte”; zaostrzenie tych zasad wydaje się krokiem wstecz
Poziom szczegółowości uprawnieńNiski poziom — działania, a nie rolePrzepisywanie każdej kontroli uprawnień
Oddzielne środowiska i dane testoweNiski — jeszcze jeden rurociągDane produkcyjne zostały już skopiowane w miejscach, których nie da się zidentyfikować
Co trafia do dziennikówZero — lista pólCenzurowanie z mocą wsteczną – i nigdy się nie dowiadujesz, kto je przeczytał

Wszystko w lewej kolumnie to rozmowa na początku projektu. Wszystko w prawej kolumnie to projekt.

Jak to działa: decyzje, jedna po drugiej

Zdecyduj, czego nigdy nie będziesz kolekcjonować

Zacznij od modelu danych, a nie od modelu zagrożeń. W przypadku każdego pola zadaj sobie pytanie, co przestanie działać, jeśli go nie będziesz mieć — nie “co moglibyśmy z tym kiedyś zrobić”, ale co przestanie działać w funkcji, którą wprowadzasz. Data urodzenia, gdy wystarczy przedział wiekowy. Pełny adres, gdy wystarczy kraj. Dokładna lokalizacja, gdy wystarczy miasto. Notatki w formie dowolnego tekstu, w których ostatecznie gromadzą się informacje, których nikt nie planował przechowywać.

Dane, których nigdy nie gromadzisz, nie mogą wycieknąć, nie mogą zostać niewłaściwie przetworzone przez SDK strony trzeciej i nie wymagają polityki przechowywania — to jedyne zabezpieczenie, którego koszty operacyjne są ujemne. Jest to również środek, którego zastosowanie staje się później niemożliwe: gdy pole już istnieje i jest odczytywane, jego usunięcie wymaga ingerencji w schemat, interfejs API, klienta oraz każdy eksport, który od niego zależy.

Minimalizacja danych polega na tym, że ochrona prywatności od samego początku przestaje być hasłem. Jako hasło oznacza ono “dbamy o prywatność” i nic nie daje. Jako decyzja skutkuje skróceniem tabeli.

Zdecyduj, gdzie będą przechowywane tajemnice, zanim ktokolwiek będzie ich potrzebował

Pierwszy klucz API projektu trafia do repozytorium, ponieważ nie ma jeszcze innego miejsca, gdzie można by go umieścić. To właśnie jest rzeczywisty mechanizm — nie chodzi o niedbalstwo, a jedynie o brak odpowiedniego miejsca docelowego. W pierwszym tygodniu należy więc utworzyć odpowiednie miejsce docelowe: sekrety w środowisku lub magazynie sekretów, wstrzykiwane w momencie wdrażania, nigdy w repozytorium, nigdy w kodzie po stronie klienta, nigdy w dokumencie udostępnionym innym osobom.

Dwie zasady, które się opłacają. Wszystko, co przechowuje klient, jest jawne — jeśli klient może to odczytać, użytkownik też może, więc klucze uprawniające do jakichkolwiek istotnych działań pozostają po stronie serwera, a klient otrzymuje token o krótkim okresie ważności. A sekret, który trafił w niewłaściwe miejsce, zostaje „spalony”: należy go rotować, zamiast usuwać commit.

Spraw, by domyślne ustawienie było niewygodne

To właśnie ta kwestia budzi spory między zespołami, więc należy to jasno określić: domyślnie zabezpieczone oznacza to, że domyślny stan jest restrykcyjny, a otwartość jest czymś, co użytkownik wybiera świadomie. Nowy wpis widoczny tylko dla jego właściciela. Udostępnianie wyłączone. Eksport wyłączony. Zakresy integracji puste. Generowanie linków publicznych wyłączone.

Obecnie nic to nie kosztuje, ponieważ nie ma użytkowników, których można by tym irytować, a później będzie to niemal niemożliwe, ponieważ do tego czasu ktoś już stworzy proces oparty na otwartym ustawieniu domyślnym, a jego zaostrzenie będzie postrzegane jako usterka, a nie poprawka. Warto wymienić związane z tym koszty: restrykcyjne ustawienie domyślne oznacza więcej kroków, a ktoś uzna to za utrudnienie. Rozwiązaniem nie jest złagodzenie domyślnego ustawienia, ale sprawienie, by udostępnienie czegoś było szybkie i przejrzyste — jedno przełączenie, jedno oświadczenie o tym, kto uzyskuje dostęp, jeden sposób na cofnięcie go. Alternatywą jest użytkownik, który nigdy nie wiedział, że jego dane zostały udostępnione.

Uprawnienia należy definiować jako czynności, a nie stanowiska

Role na początku wydają się naturalne, ale już w szóstym miesiącu ulegają sztywnieniu i przybierają niewłaściwy kształt, a rola “Admin” przejmuje wszystkie zadania, o których nikt nie chciał myśleć. Trwałe rozwiązanie opiera się na zasadzie minimalnych uprawnień na poziomie działań: kto może przeglądać ten rekord, kto może go modyfikować, kto może wyeksportować ich zbiór, kto może działać w imieniu innej osoby. Role stają się wówczas nazwanymi zestawami działań, a pojedyncze uprawnienie dla jednego użytkownika nie wymaga już tworzenia nowej roli.

Powodem, dla którego warto zająć się tym w pierwszej kolejności, są kwestie techniczne: kontrole na poziomie akcji są egzekwowane na jednej granicy, którą można poddać audytowi, podczas gdy kontrole ról są rozproszone, a przekształcenie rozproszonych kontroli w spójny model oznacza konieczność zajęcia się wszystkimi punktami końcowymi jednocześnie. Praktyczne wytyczne dla pozostałej części stosu — szyfrowanie danych w trakcie przesyłania i podczas przechowywania, walidacja po stronie serwera, brak śladów stosu w komunikatach o błędach wyświetlanych użytkownikom — zostały omówione w naszych notatkach dotyczących bezpieczeństwo w tworzeniu aplikacji internetowych; model autoryzacji to element, którego nie da się niedrogo zmodernizować.

Oddzielne środowiska i oddzielne dane

Oddzielenie środowisk to łatwiejsza część zadania i większość zespołów to robi. Część, którą się pomija, to oddzielenie danych. Zrzut danych produkcyjnych do bazy testowej to najczęstszy sposób, w jaki prawdziwe dane osobowe trafiają do miejsca o słabszej kontroli dostępu, starszym kodzie i większej liczbie osób posiadających dane uwierzytelniające. Zamiast tego należy generować dane testowe lub anonimizować je na wyjściu za pomocą skryptu uruchamianego w potoku przetwarzania, a nie na czyimś laptopie — jest to tanie w pierwszym tygodniu, ale kłopotliwe w ósmym miesiącu, gdy zestaw testów po cichu zaczyna zależeć od struktury rzeczywistych rekordów.

Zdecyduj, do czego służą logi

Logi służą do debugowania i odtwarzania przebiegu zdarzeń, dlatego muszą być szczegółowe. Czyta je też więcej osób niż samą bazę danych, a są przechowywane dłużej, niż ktokolwiek zamierzał. Na początku należy sporządzić listę pól: identyfikatory żądań, identyfikatory użytkowników, działania, wyniki, sygnatury czasowe — tak. Dane uwierzytelniające, tokeny, identyfikatory sesji, pełne treści żądań z uwierzytelnionych punktów końcowych oraz dane osobowe, które właśnie starałeś się zminimalizować — nie.

Następnie dodaj to, co większość zespołów wprowadza dopiero na późnym etapie: ścieżkę audytową dotyczącą odczytów danych wrażliwych i zmian uprawnień, oddzielną od dzienników debugowania, przechowywaną przez określony czas. “Kto przeglądał ten rekord?” – to pytanie w końcu zostanie ci zadane, a odpowiedzieć na nie można wyłącznie na podstawie danych, które już gromadziłeś.

Przykład z naszej praktyki

Dla PandaSmile, stworzona wspólnie z dr. Olivierem Setbonem w Paryżu, opracowaliśmy aplikację do cyfrowej opieki ortodontycznej w technologiach React Native i Laravel — zawierającą ćwiczenia oparte na mechanizmach gier dla pacjentów oraz powiadomienia push, które pomagają im dotrzymywać terminów.

Produkt przetwarza dane pacjentów użytkowników z UE, co oznaczało, że powyższe decyzje były na początku decyzjami projektowymi, a nie etapem wzmacniania bezpieczeństwa przed uruchomieniem. Konkretnie: przeanalizowaliśmy model danych pole po polu i usunęliśmy to, co nie było potrzebne do działania funkcji ćwiczeń i przypomnień, dzięki czemu aplikacja nigdy tych danych nie przechowywała. Dostęp został podzielony w taki sposób, aby strona kliniczna i strona pacjenta nie miały domyślnego dostępu do swoich danych, a uprawnienia były definiowane dla poszczególnych działań, a nie na podstawie roli lekarza pierwszego kontaktu. Klucze tajne i tokeny pozostawały po stronie serwera, a klienci mobilni posiadali jedynie krótkotrwałe poświadczenia. Logi zawierały identyfikatory i wyniki służące do debugowania, a nie treści kliniczne.

Żadna z tych decyzji nie wiązała się z wysokimi kosztami — były to wybory podjęte, zanim pojawiła się potrzeba migracji. Scenariusz alternatywny jasno pokazuje: usunięcie pola danych pacjenta po wdrożeniu oznaczałoby migrację schematu, ścieżkę usuwania oraz aktualizację w sklepie z aplikacjami, którą należałoby wdrożyć na każdym zainstalowanym kliencie — a wszystko to dla pola, którego nikt nie potrzebował.

Na co zwrócić uwagę

Traktuję to jako rytuał rozpoczynający. Jednorazowa sesja na początku projektu prowadzi do podjęcia decyzji, które z czasem tracą na aktualności. Trwałe rozwiązanie to stały punkt porządku obrad: każda funkcja, która dodaje pole, punkt końcowy lub integrację, wymaga udzielenia odpowiedzi na trzy pytania w ramach tej samej oceny, co wszystkie pozostałe elementy — jakie dane są gromadzone, kto ma do nich dostęp i jakie są ustawienia domyślne. To właśnie sprawia, że jest to bezpieczny cykl życia oprogramowania a nie notatka służbowa.

Opracowywanie wymagań dotyczących bezpieczeństwa, których nikt nie jest w stanie zweryfikować. “System musi być bezpieczny” nie jest wymogiem. “Żadne urządzenie końcowe nie zwraca danych innego użytkownika bez wyraźnego zezwolenia, a istnieje test sprawdzający to” – to jest wymóg. Wymogi, które nie mogą zakończyć się niepowodzeniem w teście, nie przetrwają terminu.

Mylenie tego z przestrzeganiem przepisów. Przepisy określają, co należy wykazać; koncepcja „bezpieczeństwa od samego początku” wskazuje, jakie decyzje należy podjąć na wczesnym etapie, aby później można było to wykazać. Prace projektowe same w sobie nie zapewniają certyfikacji produktu, a twierdzenie, że jest inaczej, stanowi odrębny i poważniejszy problem.

Nadmierne ograniczenia tam, gdzie nie ma to znaczenia. Nie każde pole jest wrażliwe i nie każde domyślne ustawienie wymaga zmiany. Marnowanie cierpliwości zespołu na ograniczenia o niewielkim znaczeniu podważa wiarygodność, której potrzebujesz w sprawach naprawdę ważnych.

Przejęcie działającego systemu. Okres bezpłatny już się zakończył, ale podjęte decyzje nadal mają zastosowanie do wszystkich elementów dodanych od tego momentu, a analiza wskaże, które części istniejącej powierzchni warto przenieść. Jak wygląda ten proces, opisano w co tak naprawdę obejmuje audyt kodu sztucznej inteligencji.

Wniosek

Bezpieczeństwo od samego początku sprowadza się do ustalenia kolejności działań. Należy zdecydować, jakich danych nigdy nie będziemy gromadzić, gdzie będą przechowywane poufne informacje, jakie będą ustawienia domyślne, jak będą kształtowane uprawnienia, w jaki sposób oddzielone zostaną środowiska i dane testowe oraz co będą zawierać logi — a wszystko to przy tym, że koszt zmiany decyzji ogranicza się do jednej linii w schemacie. Wszystko inne można dodać później bez konieczności migracji. To samo rozumowanie stosujemy w branży fintech, gdzie schemat jest identyczny, a stawka jest znacznie wyższa: wbudowanie zabezpieczeń w architekturę od samego początku, zamiast dodawania ich później. Jeśli rozpoczynasz projekt i chcesz, aby te decyzje były podejmowane w sposób przemyślany, to właśnie na tym polega ustalanie zakresu projektu tworzenie oprogramowania na zamówienie.

Masz już ten pomysł?

Napisz do nas, a znajdziemy najlepszy sposób realizacji Twojego pomysłu!

Zamieńmy Twój pomysł w przejrzysty plan

Typ projektu

Dziękujemy!

Odpowiemy w ciągu 24 godzin.

“Nasz zespół potrafi przekształcić każdy pomysł w rozwijający się produkt”

Taras Gopko

CEO i założyciel Appricotsoft