"Verilənlər bazasının təhlükəsizliyi yaxşı parol kimidir: sən ən çətin açarı fikirləşə bilərsən, amma onu stikerə yazıb monitora yapışdırsan — heç bir faydası olmayacaq." Ona görə də bizim məqsədimiz — təkcə müdafiə mexanizmlərini qurmaq yox, həm də bütün səyləri puç edə biləcək adi səhvlərdən qaçmağı öyrənməkdir.
1. Həddindən artıq hüquqlara malik rollardan istifadə
Çox vaxt developer-lər girişləri məhdudlaşdırmaqdan qorxurlar və geniş səlahiyyətli rollar yaradırlar, məsələn, SUPERUSER və ya ALL PRIVILEGES verirlər. Onların arqumenti belə səslənir: "Birdən lazım olar!". Amma həddindən artıq hüquqlara malik rollar təhlükəsizlikdə böyük bir dəlik yaradır.
Həddindən artıq hüquqlara nümunə:
GRANT ALL PRIVILEGES ON DATABASE university TO student_role;
Bu halda student_role bazadakı bütün məlumatlara tam giriş əldə edir. Hətta rol sadəcə oxumaq üçün nəzərdə tutulsa da, indi o, cədvəlləri silə, strukturu dəyişə və hətta adminin girişini əlindən ala bilər.
Necə qarşısını almaq olar?
Rolları minimal hüquqlarla yaradın. Buna minimal səlahiyyət prinsipi deyilir. Məsələn, məlumat oxumaq üçün rol belə olmalıdır:GRANT CONNECT ON DATABASE university TO student_role;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO student_role;
Bu yanaşma ilə student_role rolunun nə edə biləcəyini dəqiq müəyyən edirsən: baza ilə bağlantı və yalnız oxumaq.
2. Məhfuz məlumatların şifrələnməməsi
Təsəvvür et users cədvəli var və biz orada parolları adi mətn kimi saxlayırıq:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
password TEXT NOT NULL
);
Əgər kimsə bu cədvələ giriş əldə etsə, bütün istifadəçilərin parollarını əldə edəcək. Bu, evin açarlarını xalçanın altına qoymağa bənzəyir.
Bunun qarşısını almaq üçün parolları pgcrypto ilə şifrələyin. Məsələn:
CREATE EXTENSION IF NOT EXISTS pgcrypto;
INSERT INTO users (username, password)
VALUES ('johndoe', pgp_sym_encrypt('secure_password', 'encryption_key'));
Parolu yoxlamaq üçün deşifrə istifadə edə bilərsən:
SELECT username
FROM users
WHERE pgp_sym_decrypt(password::BYTEA, 'encryption_key') = 'secure_password';
Heç vaxt məxfi məlumatları açıq şəkildə saxlamayın!
3. SQL-injection-ları görməməzlikdən gəlmək
SQL-injection hələ də ən yayılmış hücum üsullarındandır və səbəbi odur ki, developer-lər hələ də sorğuları string interpolation ilə qururlar. Bax belə bir nümunə:
DO $$
DECLARE
username TEXT := 'John';
query TEXT;
BEGIN
query := 'SELECT * FROM users WHERE username = ''' || username || ''';';
EXECUTE query;
END $$;
Əgər kimsə istifadəçi adı yerinə John' OR '1'='1 göndərsə, nəticədə users cədvəlindəki bütün məlumatlar sızacaq.
Necə qarşısını almaq olar? Parametrli sorğulardan istifadə et:
PREPARE user_query (TEXT) AS
SELECT * FROM users WHERE username = $1;
EXECUTE user_query('John');
Burada dəyişən təhlükəsiz şəkildə əlavə olunur və injection mümkün deyil.
4. pg_hba.conf-un səhv ayarlanması
pg_hba.conf — IP ünvanlar üzrə girişə nəzarət üçün əsas alətdir. Onun səhv ayarlanması nəticəsində giriş lazım olandan daha geniş açıq ola bilər.
Pis konfiqurasiya nümunəsi:
host all all 0.0.0.0/0 trust
Bu sətr hər hansı istifadəçiyə istənilən IP-dən istənilən bazaya parolsuz qoşulmağa icazə verir.
Necə qarşısını almaq olar? Girişi yalnız konkret IP-lərə ayarlayın və md5 və ya scram-sha-256 autentifikasiya metodundan istifadə edin:
host university student_role 192.168.1.0/24 md5
Bu, student_role üçün yalnız lokal şəbəkədən və parolla girişə icazə verir.
pg_hba.conf-da dəyişiklik etdikdən sonra, onları tətbiq etməyi unutma:
pg_ctl reload
5. ROW LEVEL SECURITY-nin səhv istifadəsi
RLS — güclü alətdir, amma düzgün ayarlanmasa və ya aktiv edilməsə, heç bir faydası yoxdur. Məsələn, giriş siyasəti yazılsa belə, RLS söndürülübsə işləməyəcək:
CREATE POLICY my_policy ON users
USING (username = current_user);
-- Amma RLS aktiv deyil!
SELECT * FROM users; -- Bütün sətrləri görəcəksən!
Necə qarşısını almaq olar? RLS-i aktiv etməyi unutma:
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
Və siyasətin necə işlədiyini yoxla:
SET ROLE student_role;
SELECT * FROM users; -- Yalnız siyasətə uyğun sətrlər görünəcək.
6. Administratorların nəzərə alınmayan hərəkətləri
Bəzən verilənlər bazası administratorları bütün məlumatlara tam girişə malik olurlar, halbuki bu, onların işləri üçün lazım deyil. Əgər admin hesabı komprometasiya olunsa, bu əlavə sızma riski yaradır.
Necə qarşısını almaq olar? Rolları ayırın. Admin işləri üçün ayrıca, məlumatlara girişsiz rol yaradın:
CREATE ROLE admin_role WITH LOGIN CREATEDB CREATEROLE;
Məlumatlara giriş üçün isə minimal hüquqlu başqa rol yaradın:
CREATE ROLE data_analyst_role;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO data_analyst_role;
İstifadəçiyə tapşırıqlarına uyğun rolları təyin edin:
GRANT admin_role TO some_user;
GRANT data_analyst_role TO another_user;
7. Qeyri-kafi loglama
Əgər loglama ayarlanmayıbsa, şübhəli hərəkətlərdən xəbər tutmayacaqsan — artıq gec olmayınca.
Loglamanın olmamasına nümunə:
-- postgresql.conf faylında heç bir ayar yoxdur
log_statement = 'none';
Necə qarşısını almaq olar? Ən azı əsas loglamanı aktiv et:
log_statement = 'all'
log_connections = on
log_disconnections = on
Bu, bütün sorğuları, bağlantı və ayırmaları görməyə imkan verəcək.
Daha detallı nəzarət üçün pgAudit extension-u ilə audit də qura bilərsən:
CREATE EXTENSION pgaudit;
8. Köhnəlmiş autentifikasiya metodlarından istifadə
password kimi köhnəlmiş autentifikasiya metodlarından istifadə kifayət qədər müdafiə etmir.
Necə qarşısını almaq olar? Daha təhlükəsiz metodlara, məsələn, scram-sha-256-ya keç:
ALTER SYSTEM SET password_encryption = 'scram-sha-256';
Və istifadəçi parollarını yenilə:
ALTER USER student_role WITH PASSWORD 'new_secure_password';
Bu problemlər xırda görünə bilər, amma hər biri ciddi təhlükəsizlik boşluğuna çevrilə bilər. Sənin vəzifən — verilənlər bazasını elə idarə etməkdir ki, sanki hər bir istifadəçi şübhəlidir. Deyirlər ki, "etibar et, amma yoxla". İndi sənin əlində təkcə təhlükəsizlik ayarları yox, həm də ən yayılmış səhvlərin qarşısını almaq üçün alətlər var. Şansını əldən vermə və qoy məlumatların həmişə təhlükəsiz olsun!
GO TO FULL VERSION