Deməli, əvvəlcə bilək görək, nəyi qoruyuruq, daha doğrusu – kimdən qoruyuruq. Bu səviyyənin əvvəlində artıq SQL-injection-lardan danışmışdıq, bunlar bazalara qarşı ən məşhur və dağıdıcı hücumlardandır. Hücum belə işləyir: pis niyyətli biri sənin SQL sorğuna zərərli kod göndərir ki, onu "aldatsın" və əslində icazəsi olmayan məlumatlara çıxış əldə etsin. İndi gəlin, bu mövzuya bir az daha dərindən baxaq.
SQL-injection nümunəsi
Tutaq ki, sənin web-applikasiyan var və orada istifadəçi adı və şifrə daxil etmək üçün sadə bir input var. Backend SQL-sorgu icra edir ki, istifadəçi bazada var, ya yox:
SELECT * FROM users WHERE username = 'admin' AND password = 'password123';
Bu sorğu əla görünür... ta ki, istifadəçi normal məlumat daxil edənə qədər. Amma görək, kimsə belə daxil etsə nə baş verər:
- İstifadəçi adı:
admin' -- - Şifrə: (bura heç nə yazmırıq)
Nəticədə sorğu belə bir şeyə çevrilir:
SELECT * FROM users WHERE username = 'admin' -- AND password = 'password123';
Burada -- simvollarına fikir ver, SQL-də bu, şərh (comment) başlanğıcıdır. Ondan sonra gələn hər şey sayılmır. Nəticədə şifrə yoxlanışı sadəcə ötürülür və pis niyyətli adam admin kimi daxil olur!
SQL-injection-un potensial nəticələri
SQL-injection həqiqətən dəhşətli nəticələrə gətirib çıxara bilər:
- İcazəsiz məlumatlara çıxış. Məsələn, pis niyyətli biri istifadəçi şifrələri kimi gizli məlumatları əldə edə bilər.
- Məlumatların silinməsi və ya dəyişdirilməsi. Kimsə bütün cədvəli silə və ya ora xaos sala bilər.
- İstənilən SQL kodunun icrası. Təsəvvür elə, biri
DROP DATABASEəmri işə salır... Hə, bu, əsl kabusdur.
Amma biz qorxaq deyilik! PostgreSQL bizə belə hücumlardan qorunmaq üçün bir dəstə alət verir.
Necə qorunmalı? SQL-injection-un qarşısını almaq üçün metodlar
- Prepared queries istifadə etmək (
PREPAREvəEXECUTE)
Prepared queries – sənin SQL kodun üçün sanki yoxlanmış resept kimidir. Belə işləyir: sən SQL-sorgunu bir dəfə "hazırlayırsan", sonra isə ora məlumatları ayrıca ötürürsən. Bu, zərərli kodun daxil edilməsini mümkünsüz edir.
Bax, düzgün yanaşmanın nümunəsi:
Sorğunu PREPARE ilə hazırla.
PREPARE user_login (text, text) AS
SELECT *
FROM users
WHERE username = $1 AND password = $2;
Burada iki parametr $1 və $2 var və real dəyərlər sonradan ötürüləcək.
Sorğunu icra etmək üçün EXECUTE istifadə et.
EXECUTE user_login('admin', 'password123');
Bu zaman PostgreSQL avtomatik olaraq bütün user məlumatlarını escape edir və zərərli SQL kodunun daxil edilməsinin qarşısını alır.
Bu yanaşmanın üstünlükləri:
- SQL-injection etmək mümkün deyil, çünki parametrlər sadəcə data kimi işlənir, SQL kodunun bir hissəsi kimi yox.
- Sorğular daha təhlükəsiz olur və execution plan cache-ləndiyinə görə daha sürətli işləyir.
- Parameterized queries
Bu metod xüsusilə Python və ya Java kimi proqramlaşdırma dillərində yazılmış applikasiyalarda məşhurdur. PREPARE və EXECUTE ilə əllə işləmək əvəzinə, sən kitabxana və ya ORM istifadə edə bilərsən, onlar parametrləri avtomatik işləyir.
Python və psycopg2 kitabxanası ilə nümunə:
import psycopg2
connection = psycopg2.connect(
dbname="your_db",
user="your_user",
password="your_password",
host="localhost",
port="5432"
)
cursor = connection.cursor()
# Parameterized query istifadə edirik
username = "admin"
password = "password123"
query = "SELECT * FROM users WHERE username = %s AND password = %s"
cursor.execute(query, (username, password))
# Sənin məlumatların tam təhlükəsizdir!
result = cursor.fetchall()
print(result)
Burada %s SQL-sorğuda parametrin yeridir. psycopg2 kitabxanası məlumatların təhlükəsiz ötürülməsinə özü nəzarət edir.
- Input yoxlaması
Əgər user-dən gələn məlumatı ötürürsənsə, əmin ol ki, onlar sənin gözlədiyin formadadır. Məsələn:
- Text məlumatlar üçün regular expression istifadə et ki, orada qadağan olunmuş simvollar olmasın.
- Rəqəm üçün əmin ol ki, həqiqətən rəqəmdir.
Python-da nümunə:
import re
username = input("İstifadəçi adını daxil et: ")
# Yalnız hərf, rəqəm və alt xətt icazə veririk
if re.match(r"^\w+$", username):
print("İstifadəçi adı düzgündür")
else:
print("Təhlükəli istifadəçi adı!")
- Minimal privilege-lərdən istifadə
Əmin ol ki, sorğuları icra edən rolların yalnız lazım olan minimal privilege-ləri var. Məsələn, əgər ehtiyac yoxdursa, DROP TABLE və ya ALTER TABLE icazəsi vermə.
- Şübhəli hərəkətlərin log-lanması
PostgreSQL parametrlərindən istifadə edərək user aktivliyini izləyə bilərsən:
log_statement = 'all'— bütün sorğuların log-lanması.log_connections = on— bazaya bütün bağlantıların log-lanması.
Bu parametrlər potensial təhlükəli hərəkətləri aşkar etməyə kömək edir.
İcra nümunələri
Nümunə 1: SQL ilə prepared query istifadə etmək
-- Prepared query yaradırıq
PREPARE check_credentials (text, text) AS
SELECT * FROM users WHERE username = $1 AND password = $2;
-- Təhlükəsiz parametrlərlə sorğunu icra edirik
EXECUTE check_credentials('admin', 'password123');
Nümunə 2: Python-da parameterized query
query = "UPDATE users SET last_login = NOW() WHERE username = %s"
username = "admin"
cursor.execute(query, (username,))
Təhlükəsizlik üçün tövsiyələr
Həmişə input-u yoxla. Heç vaxt user-dən gələn məlumata tam etibar etmə.
Yalnız prepared queries və ya parameterized queries istifadə et. Bunlar sənin SQL-injection-a qarşı əsas qalxanındır.
Rollara yalnız lazım olan minimal privilege-lər ver. Əgər pis niyyətli biri daxil olsa belə, zərər minimum olacaq.
Log-lamaları qur və log-ları mütəmadi yoxla. Bazanda baş verənlərdən xəbərdar ol.
SQL-injection əlbəttə ki, qorxulu bir şeydir, amma prepared queries, parameterized queries və yaxşı praktikalara əməl etsən, bazanı qoruyacaqsan və gecələr rahat yatacaqsan – heç kim "təsadüfən" bütün cədvəllərini silə bilməyəcək. PostgreSQL sənə bunun üçün bütün alətləri verir, ona görə də buyur, işə başla!
GO TO FULL VERSION