Bezpieczeństwo danych w nowoczesnych relacyjnych systemach bazodanowych

bezpieczenstwo danych

Wraz ze wzrostem świadomości znaczenia bezpieczeństwa, w systemach IT rośnie nacisk na zabezpieczenia poszczególnych komponentów, ale jednocześnie zwiększa się także ilość wektorów ataku. W tym artykule postaram się przybliżyć zagadnienie bezpieczeństwa w systemie bazodanowym. Jako przykład zostanie użyta baza EuroDB oparta o silnik PostgreSQL.

Na początek przeanalizujemy przypadek bazy danych pracującej w pojedynczej instancji. Poza szczególnymi przypadkami do bazy danych podłączają się klienci i administratorzy.

System bazodanowy składa się w dużym uproszczeniu z plików z danymi i meta danymi, plików binarnych silnika bazodanowego (na dysku i w pamięci) oraz obszarów pamięci wykorzystywanej przez te procesy, a także wykorzystywanej jako pamięć podręczna serwera.

Dane na dysku chronione są na zasadzie nadawania i weryfikowania odpowiednich uprawnień. Natomiast pamięć operacyjna chroniona jest przez sam koncept architektury współczesnych procesorów. W systemach bazujących na Enterprise Linux możliwa jest również obowiązkowa kontrola dostępu (Mandatory Acces Control) implementowana przez rozszerzenie jądra Security Enhanced Linux (SELinux). Wrócimy do tego zagadnienia w dalszej części. Chwilo skupię się na plikach samych w sobie. Baza danych po zamknięciu w poprawny sposób zawiera sto procent danych w plikach zapisanych na dyskach. Z tych plików programy i dane ładowane są do pamięci operacyjnej celem realizacji swojego podstawowego zadania. Możemy wyobrazić sobie zabezpieczenie tych danych poprzez zaszyfrowanie ww. plików na niższych poziomach. Wśród dostępnych realizacji znajdują się m.in.: LUKS (zaszyfrowane woluminy logiczne), szyfrowanie jednostek logicznych na macierzach (LUN encryption), szyfrowanie danych na samych dyskach twardych przy użyciu ich firmware. Dochodzi do tego też pewien stopień zaciemnienia wynikającego z samego procesu konwergencji w nowoczesnych centrach danych. Zatem potencjalny atak na nośnik fizyczny wymagałby wiedzy, na którym konkretnie urządzeniu znajdują się dane bazy będącej celem ataku, a także możliwość odbudowania takiego układu. Jednakże w przypadku, kiedy aplikacja nie jest świadoma realizacji szyfrowania na niższych warstwach (co jest prawdziwe dla ogromnej większości baz danych), wymaga dostępu do danych już odszyfrowanych. Innymi słowy, gotowa do działania baza danych nie czerpie benefitów związanych z bezpieczeństwem wynikających z szyfrowania nośnika, na którym znajdują się dane. Albo mówiąc jeszcze prościej, szyfrowanie nośników, które stale pracują, a więc są odszyfrowane, nie ma większego sensu. Bo czy ktoś słyszał o wtargnięciu do serwerowni i kradzieży dysków? Atakujący usiłują się dyskretnie włamać do systemów i baz pracujących online. Na szczęście są inne zabezpieczenia, które skutecznie zapobiegają takim możliwościom, a które oferuje między innymi EuroDB.

Zanim zagłębimy się dalej w kwestiach szyfrowania danych, warto zwrócić uwagę na bezpieczeństwo danych w kontekście ich potencjalnego uszkodzenia bądź degradacji. W standardowej implementacji PostgreSQL dane zapisywane są do plików danych w sposób zgodny z parametrami podanymi w trakcie kompilacji. Następnie dane są odczytywane z dysku w momencie, w którym są potrzebne. Jeżeli z jakiegoś powodu zapis został uszkodzony, ale z punktu widzenia systemu plików (a za tym także jądra systemu operacyjnego, jak i samej aplikacji bazodanowej) został uznany za skuteczny, dane są uszkodzone. Co więcej, żaden z elementów systemu nie jest tego świadom i baza danych może zwracać poprawne (według swojej logiki) dane, które jednocześnie nie są poprawne (nie są tymi, które zapisano). Kolejnym problemem może być manualna ingerencja strony trzeciej w pliki bazodanowe (poza procesem bazodanowym), co oczywiście prowadzi do podobnych efektów, jak w przypadku uszkodzenia. Jednakże w sytuacji zamierzonego działania skutki mogą być o wiele poważniejsze. Przed tego typu problemami pozwala się ustrzec mechanizm sum kontrolnych zaimplementowany w EuroDB. Dzięki niemu każda strona danych (blok danych w pojęciu bazodanowym) jest zaopatrzona w sumę kontrolną. Pozwala to na weryfikację integralności danych wewnątrz samego procesu bazodanowego. W tym wypadku, jeżeli jakikolwiek blok danych będzie miał po odczycie niepoprawną sumę kontrolną, cały klaster zostanie zatrzymany automatycznie celem zapobieżenia dalszej utracie danych.

Wiedząc już, jak możemy zabezpieczyć integralność plików bazy danych, należy rozpatrzyć przypadek, w którym to w systemie operacyjnym dochodzi bądź do eskalacji uprawnień do poziomu superużytkownika, bądź do nieautoryzowanego dostępu do konta o tym poziomie uprawnień. Do tej samej grupy należy również świadome działanie osoby, której dostęp jest autoryzowany, a która wykonuje nieautoryzowane operacje bądź wręcz operacje wrogie. Pominąwszy warstwę izolacji sieciowej i powiązanych z nią metod kontroli dostępu, otrzymujemy sytuację, w której w systemie operacyjnym kontrola nad „rootem” została przejęta. Z punktu widzenia aplikacji bazodanowej wszystkie operacje w takiej sytuacji traktowane są jako autoryzowane. Superużytkownik systemu operacyjnego może dostać się do bazy danych, nawet jeżeli jej aktualna konfiguracja na to nie pozwala.

Jak chronić dane w takim wypadku?

Nie eksploatując dodatkowo tematu numerów kart kredytowych (które ponadto zwykle przechowywane są i tak bez kodu CVV, a więc są mniej atrakcyjne), weźmy jako przykład bazę danych, w której znajduje się tabela chorób przewlekłych zawierająca między innymi opis oraz identyfikator. Ponadto znajduje się tam tabela pacjentów zawierająca identyfikator choroby przewlekłej, na którą cierpi dany pacjent. Upublicznienie takiego zestawu informacji byłoby niepowetowaną stratą zarówno dla pacjentów, jak i dla samej organizacji, która do wycieku danych doprowadziła. Celem tego artykułu nie jest rozważanie nad socjologicznymi, prawnymi i materialnymi skutkami takiej kompromitacji więc zostawiam to wyobraźni czytelników. W przypadku bazy danych EuroDB możliwe jest stosowanie dodatkowych, względem PostgreSQL, typów danych, takich jak: zaszyfrowane liczby zmiennoprzecinkowe, zaszyfrowane liczby całkowite, zaszyfrowany tekst. W tym wypadku aplikacja przekazuje zaszyty w niej klucz szyfrujący, który przekazywany jest do stosownej funkcji na początku sesji (zwykle w trakcie polecenia „connect”), a następnie pola traktowane są, jak normalne pola tego typu (mogą być używane na przykład w złączeniach). W bazie danych natomiast zapisywana jest zaszyfrowana mechanizmem AES512 wartość. W tym wypadku wejście w posiadanie takiej bazy danych zostawia atakującego z bezużytecznym zestawem danych.

Możemy rozwinąć ten scenariusz jeszcze dalej i wyobrazić sobie sytuację, w której użytkownik przechowuje hasło i nie jest ono nigdzie składowane. W tym wypadku dane powiązane z konkretnym użytkownikiem zaszyfrowane są jego dedykowanym kluczem. Dzięki takiemu rozwiązaniu nawet użytkownik posiadający dostęp do bazy oraz swój klucz szyfrujący nie jest w stanie odszyfrować rekordów pozostałych użytkowników.

Pozostając na poziomie zabezpieczeń bazy danych, ale z pominięciem enkrypcji na rzecz zdecydowanie bardziej wydajnych mechanizmów bazodanowych EuroDB, tak jak inne rozwiązania bazodanowe klasy Enterprise, pozwala na wprowadzenie zabezpieczeń na poziomie wiersza (Row Level Security). Za pomocą tego mechanizmu możemy wspomóc regułami bazodanowymi zabezpieczenia już zawarte w aplikacji. Analizując przykład aplikacji, gdzie użytkownik korzysta z aplikacji, która wspierana jest przez silnik bazodanowy, możemy zaobserwować, że w standardowym przypadku aplikacja wybiera z bazy danych rekordy powiązane z użytkownikiem. Jednakże za sprawą błędu w aplikacji (SQL Injection) możliwe jest, korzystając z zestawionej sesji, pobranie z bazy danych wszystkich rekordów z tabel, do których użytkownik ma dostęp. Można wspomóc ten proces tak, aby w kontekście połączenia zadanego użytkownika mógł on pobrać tylko rekordy, do których ma uprawnienia. Odbywa się to całkowicie transparentnie, tak więc atakujący nie wie, czy otrzymał z bazy danych wszystkie rekordy, czy tylko te, dla których zostały spełnione zasady RLS. Jest to dodatkowa warstwa, która pozwala na zwiększenie poziomu bezpieczeństwa całego rozwiązania.

Kolejnym aspektem bezpieczeństwa jest mechanizm połączenia do bazy danych za pomocą sieci.
Dotyczy to zarówno aspektu opisywanego powyżej, jak i przypadku klastrów baz danych z mechanizmami replikacji. W przypadku EuroDB połączeniami agentów replikacji zarządza się w ten sam sposób, w jaki konfiguruje się zasady połączenia normalnych użytkowników. Zatem poniższe akapity dotyczą zarówno bezpieczeństwa połączenia, jak i integralności replikacji. O replikacji pisałem w poprzednim artykule.

W przypadku podłączenia do bazy danych korzystając z sieci komputerowej, pojawia się naturalne zagrożenie w postaci ataku MitM (podsłuch transmisji w jej trakcie). Nowoczesne systemy bazodanowe zabezpieczają przed takim atakiem, szyfrując komunikację. W ramach konwergencji w zakresie wykorzystania technologii, w przypadku rozwiązań opartych o PostgreSQL, jest to implementacja TLS przy użyciu bibliotek OpenSSL. W domyślnej konfiguracji EuroDB weryfikowany jest cały łańcuch certyfikacji, włączając w to certyfikat głównego organu certyfikacji. Stopień złożoności obliczeniowej mechanizmów szyfrujących jest w tym wypadku regulowany poza rozwiązaniem bazodanowym, stosując odpowiednią długość i rodzaj klucza.

Na przedstawionych przykładach można zaobserwować, że współczesne rozwiązania bazodanowe nadążają za zapotrzebowaniem na bezpieczeństwo w środowisku baz danych oraz mogą wesprzeć rozwój aplikacji w zakresie bezpieczeństwa.

W artykule nie zaadresowano zagadnienia pełnego wsparcia dla Mandatory Access Control obecnego w systemie z rodziny Enterprise Linux (SELinux) w ramach bazy danych. Platforma EuroDB zapewnia tę możliwość i wiele innych rozszerzeń PostgreSQL, o czym możesz przeczytać na stronie produktu.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *