C, PHP, VB, .NET

Дневникът на Филип Петров


* Защита на базата от данни

Публикувано на 21 ноември 2008 в раздел ОСУП.

При всяка система, свързана с автентикация, има едно особено критично звено, което трябва да бъде пазено на всяка цена - базата от данни с имена и пароли на потребителите. На първо място трябва да отбележим няколко практични съвета за администриране на такава база от данни:

1. Заключете сървъра за бази от данни за външния свят. Стандартно сървъра би трябвало да приема връзки само от localhost и да не "слуша" за автентикация на никакви портове (пример стандартно 3306 за MySQL). Ако все пак вашето приложение е качено на един сървър, а базата от данни е сложена на друг - настройте защитната стена на сървъра с базата от данни така, че да приема заявки само от IP адреса на уеб приложението. Сменете стандартния порт, така че евентуално да заблудите автоматични brute force кракери от вашата мрежа.

2. Давайте само тези права на DB user, които са му нужни. Повреждането или унищожаването на базата от данни е достатъчно лошо за вашата система, въпреки че не толкова фатално както изтичането на информация. Модула за проверка на автентикация на потребител би трябвало да използва само SELECT заявка към сървъра с базата от данни. Създайте му потребител, който има само SELECT права и нищо друго. Друг пример - в административния панел на потребителя, където той евентуално може да си смени паролата, би трябвало да се използват само UPDATE заявки. Въпреки, че при пробив в сигурността на приложението и SELECT и UPDATE могат да доведат до достатъчно лоши последици, такава мярка все пак не е за пренебрегване (най-малкото ще бъде проява на добра организация на системата).

3. Когато вашето приложение изпълнява заявка - погрижете се да затворите връзката към сървъра възможно най-бързо след приключването й. Няма практическа полза да държите постоянна връзка с базата от данни - това може да спестява някакво минимално количество ресурси, но пък поставя големи въпросителни за сигурността.

4. Направете добър дизайн на системата си. Трябва ли административните потребители да са в една и съща таблица с обикновените? Колкото и да е удобно това, може би трябва да помислите за отделна таблица/база за администраторите и различна форма за автентикация (със значително по-строг режим на достъп).

5. Поставете разумен максимум на максималният брой връзки към базата от данни.

6. Забравихте ли за username "root"? Това се отнася главно за MySQL бази от данни, където при стандартна инсталация потребителя root има пълни права над сървъра и ... няма парола. Този потенциален проблем може да се забележи на доста малки сървъри. Задължително след инсталиране на MySQL сървър се погрижете да зададете парола на root потребителя! Друг основен закон - никога не използвайте този потребител за достъп от вашите приложения!

7. Използвайте SSL. Когато вашият сървър за база от данни е на отделна машина, то е задължително да криптирате комуникацията (например между PHP и MySQL това става с флаг MYSQLI_CLIENT_SSL). Не се доверявайте на сигурността на локалната си мрежа - дори само един компрометиран компютър в нея би могъл да подслуша вашият вътрешен трафик.

8. Филтрирайте SQL заявките! Ще разгледаме специално този проблем в по-следваща тема.

9. Защитата на резервните копия на системата е точно толкова важна, колкото и защитата на самата система.

Всичко дотук е добре, но въпреки това - какво ще стане ако някой все пак успее да придобие копие на базата ви от данни или части от нея? Отговорът е, че можем да сведем щетата до минимум ако в базата от данни използваме криптирана информация! Нека например разгледаме схема на автентикация на обикновена база от данни:

DB, която не използва криптиране на данните
DB, която не използва криптиране на данните

От картинката се вижда ясно - въпреки, че връзката между клиента и сървъра е криптирана, ние все още имаме слабо звено в системата. При кражба на данни от базата от данни резултатите за сигурността са фатални!

Очевидно, е че складирането на информацията като обикновен текст е напълно неразумна. Затова всяка разумна система за автентикация трябва да използва криптография:

Криптирана база данни
Криптирана база данни

Като оставим настрана фактът, че имаме пробив в сигурността (някой е откраднал базата от данни), ние все пак успяхме относително да защитим нашата информация. От тук нататък защитата е в ръцете на криптографският алгоритъм. При подобно изтичане на информация бихме се чувствали защитени само и единствено ако сме спазвали следните правила:

1. Използвали сме силен криптографски алгоритъм.
2. Използвали сме политика за използване на трудни за отгатване пароли.
3. Използваме политика за промяна на паролата на достатъчно къс период от време.

Последната точка е изключително важна. Трябва да приемем, че рано или късно криптографският алгоритъм, който използваме ще бъде разбит чрез brute force атаки (атакуващият изпробва всякакви възможни комбинации от букви, цифри и символи докато не получи съвпадение). Ако ние пазим и използваме едни и същи пароли в продължение на години, то със сигурност трябва да приемем, че сме уязвими. Затова променяйте паролите в системата си през интервали в зависимост от политиката ви за сложност на паролите и в зависимост от криптографията, която използвате.

Друг принцип, който все още не сме споменали е следният: никога не складирайте конфиденциална информация, освен ако не е напълно наложително. Ако например предлагате услуга с годишен абонамент на вашите потребители - дали е нужно да пазите кредитните им карти в база от данни (с цел автоматично подновяване на услугата)? Не е ли по-добре да отстъпите от удобството и да ги накарате веднъж годишно да въвеждат номера на своята кредитна карта ръчно и той да не се записва никъде след трансакцията?

П.С. Ако все пак си мислите, че атаката "кражба на база от данни" е невъзможна за реализиране, то помислете над следния въпрос - какво доверие бихте гласували на вашият администратор на база от данни? Дали той би трябвало да може да вижда всички конфиденциални данни в нея?

 



Добави коментар

Адресът на електронната поща няма да се публикува


*