
Veritabanı Güvenliği: SQL Injection Önleme ve Erişim Kontrolü
Veritabanı güvenliği: SQL injection saldırıları ve önleme, en az yetki prensibi, veritabanı şifreleme ve güvenlik denetimi.
Veritabanı Güvenliği: SQL Injection Önleme, Erişim Kontrolü, Şifreleme (2026 Pratik Rehber)
Veritabanı, web uygulamasının değerli varlığını saklayan kasa. Müşteri bilgisi, sipariş, e-posta, ödeme verisi — hepsi MySQL/MariaDB tablolarında duruyor. Saldırgan veritabanına eriştiği an iş bitmiştir: KVKK ihlali, rakip eline veri, müşteri tepkisi, regulatör ceza. Bu rehberde Buyukweb cPanel + VDS müşterilerimiz için veritabanı güvenliğinin gerçekten anlamlı kademelerini anlatıyoruz: SQL injection önleme, en az yetki, parola politikası, ağ erişimi, denetim. Pazarlama klişesi yok; her madde uygulanabilir.
Buyukweb perspektifi: cPanel paylaşımlı hosting'imizde veritabanı sunucu seviyesinde CageFS izolasyon + CSF + ModSecurity + Imunify360 (opsiyonel ek) ile korunuyor. Müşteri seviyesinde sorumluluk uygulama kodu: SQL injection önleme, prepared statement kullanımı, dosya yetkileri. Tercih etmeyin: "tek admin user ile hızlı kurulum" yaklaşımını — root user'ı her uygulama için kullanırsanız bir SQL injection sunucu çapına yayılır. Her uygulama için ayrı veritabanı + ayrı user + en az yetki.
SQL Injection: En Yaygın Veritabanı Saldırısı
OWASP Top 10'da onlarca yıldır 1. veya 2. sırada. İlk teknik açıklama:
Saldırı Senaryosu
Aşağıdaki PHP kodu kötü — kullanıcı girdisini doğrudan SQL'e ekliyor:
// ❌ TEHLİKELİ — sql injection açık
$username = $_GET['username'];
$query = "SELECT * FROM kullanicilar WHERE username = '$username'";
$result = mysqli_query($conn, $query);
Saldırgan username parametresine ' OR '1'='1 gönderirse:
SELECT * FROM kullanicilar WHERE username = '' OR '1'='1'
-- Tüm kullanıcı kayıtlarını döner!
Daha kötü: '; DROP TABLE kullanicilar; --:
SELECT * FROM kullanicilar WHERE username = ''; DROP TABLE kullanicilar; --'
-- Tablo siler!
Prepared Statement (Çözüm)
// ✅ GÜVENLİ — prepared statement
$stmt = $conn->prepare("SELECT * FROM kullanicilar WHERE username = ?");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();
Prepared statement kullanıcı girdisini veri olarak alır, SQL kodu olarak yorumlamaz. Saldırı pratik olarak imkansız hale gelir.
PDO ile (Modern PHP)
// ✅ PDO + Prepared Statement
$pdo = new PDO('mysql:host=localhost;dbname=site', $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false // gerçek prepared kullan
]);
$stmt = $pdo->prepare("SELECT * FROM kullanicilar WHERE username = :user");
$stmt->execute(['user' => $username]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
ORM Kullanımı (En Güvenli)
Modern framework'lerin ORM'i (Eloquent — Laravel, Doctrine — Symfony, Sequelize — Node, Prisma — Node) prepared statement'ı otomatik kullanır:
// Laravel Eloquent — sql injection imkansız
$user = User::where('username', $request->username)->first();
// Doctrine
$user = $em->getRepository(User::class)->findOneBy(['username' => $username]);
// Prisma (Node.js)
const user = await prisma.kullanici.findFirst({ where: { username } });
Kural: Üretim koduna asla string concatenation ile SQL inşa etmeyin. Mutlaka prepared statement veya ORM. Bu tek pratik %99 SQL injection saldırısını engeller.
En Az Yetki Prensibi (Principle of Least Privilege)
WordPress veya custom uygulamanız MySQL'e bağlanırken root kullanıcı kullanmayın. Her uygulama için özel kullanıcı + sadece gerekli yetki.
Yanlış (Tehlikeli)
-- ❌ Tüm yetkiler ALL — DROP DATABASE bile yapabilir
GRANT ALL PRIVILEGES ON *.* TO 'wpuser'@'%' IDENTIFIED BY 'pass123';
Doğru
-- ✅ Sadece spesifik veritabanı + sadece gerekli işlemler
CREATE USER 'wp_buyukweb'@'localhost' IDENTIFIED BY 'GUCLU_PAROLA_16+';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, REFERENCES
ON wp_buyukweb.* TO 'wp_buyukweb'@'localhost';
FLUSH PRIVILEGES;
-- Sadece okuma için reporting user
CREATE USER 'reporting_ro'@'localhost' IDENTIFIED BY 'BASKA_PAROLA';
GRANT SELECT ON wp_buyukweb.* TO 'reporting_ro'@'localhost';
Yetki Listesi
| Yetki | Anlamı | Kullanım |
|---|---|---|
| SELECT | Okuma | Hemen her uygulamaya gerek |
| INSERT | Yeni kayıt | Çoğu uygulama |
| UPDATE | Güncelleme | Çoğu uygulama |
| DELETE | Silme | Çoğu uygulama |
| CREATE | Yeni tablo oluştur | Sadece kurulum/upgrade |
| DROP | Tablo sil | Sadece geliştirme, prod'da YOK |
| ALTER | Tablo yapısı değiştir | Migration |
| GRANT OPTION | Yetki devret | Sadece super admin |
| FILE | LOAD/SELECT INTO OUTFILE | Tehlikeli — verme |
| SUPER | Replikasyon, ayar değiştir | Sadece DBA |
WordPress Özel Senaryosu
WordPress kurulumu sırasında CREATE, ALTER yetkisi gerek; sonra kaldırılabilir:
-- Kurulum sonrası kaldır (eklenti/tema güncellemesi gerekirse geri ver)
REVOKE CREATE, ALTER, DROP ON wp_buyukweb.* FROM 'wp_buyukweb'@'localhost';
Veritabanı Erişim Ağı Sınırlama
MySQL/MariaDB Bind Address
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
bind-address = 127.0.0.1 # sadece localhost
# bind-address = 0.0.0.0 # ❌ public — kullanmayın
sudo systemctl restart mariadb
Uzak Erişim Gerekli Senaryosu
Web sunucusu ve DB sunucu farklı VDS'te ise spesifik IP'ye izin:
-- Sadece web sunucu IP'sinden bağlanma
CREATE USER 'wp_buyukweb'@'195.85.100.50' IDENTIFIED BY 'PAROLA';
GRANT SELECT, INSERT, UPDATE, DELETE ON wp_buyukweb.* TO 'wp_buyukweb'@'195.85.100.50';
Veya wildcard:
-- 195.85.100.0/24 ağ aralığından
CREATE USER 'wp_buyukweb'@'195.85.100.%' IDENTIFIED BY 'PAROLA';
Firewall Kuralı
# UFW — sadece web sunucu IP'sinden 3306'a izin
sudo ufw allow from 195.85.100.50 to any port 3306
sudo ufw deny 3306
# CSF (cPanel)
# /etc/csf/csf.allow:
tcp:in:d=3306:s=195.85.100.50
Parola Politikası
-- MariaDB / MySQL parola politikası
SET GLOBAL validate_password.policy = STRONG;
SET GLOBAL validate_password.length = 16;
SET GLOBAL validate_password.mixed_case_count = 2;
SET GLOBAL validate_password.number_count = 2;
SET GLOBAL validate_password.special_char_count = 2;
DBA Best Practice: 16+ karakter, harf+rakam+sembol kombinasyonu, password manager kullanın (1Password, Bitwarden), default user'lar (root, admin) için boş parola asla.
Bcrypt ile Application-Level Parola Saklama
Web uygulamanızda kullanıcı parolaları için:
// PHP - parola oluşturma
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]);
// PHP - parola doğrulama
if (password_verify($password, $hash)) {
// başarılı
}
// Node.js
const bcrypt = require('bcrypt');
const hash = await bcrypt.hash(password, 12);
const ok = await bcrypt.compare(password, hash);
Argon2id (daha modern), bcrypt (sektör standardı), PBKDF2 (FIPS uyumlu) — bu üçünden birini kullanın. Md5, SHA1, SHA256 ile parola hash'leme YANLIŞ — kırılması saniyeler sürer.
SSL/TLS ile Veritabanı Bağlantı Şifreleme
# /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
ssl-ca = /var/lib/mysql/ca-cert.pem
ssl-cert = /var/lib/mysql/server-cert.pem
ssl-key = /var/lib/mysql/server-key.pem
require_secure_transport = ON
-- Kullanıcı için SSL zorunlu
ALTER USER 'wp_buyukweb'@'localhost' REQUIRE SSL;
Aynı sunucu içinde (localhost-only) gerek yok; uzak DB sunucu için kritik.
Hassas Verilerin Şifrelenmesi (Application-Level)
KVKK gereği kişisel veriler veritabanında şifrelenmiş olmalı. Senaryo: telefon, TC kimlik, kart numarası. Çözüm: uygulama seviyesi şifreleme:
// AES-256-GCM ile şifreleme
function encrypt($plaintext, $key) {
$iv = random_bytes(16);
$tag = '';
$cipher = openssl_encrypt($plaintext, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
return base64_encode($iv . $tag . $cipher);
}
function decrypt($encoded, $key) {
$data = base64_decode($encoded);
$iv = substr($data, 0, 16);
$tag = substr($data, 16, 16);
$cipher = substr($data, 32);
return openssl_decrypt($cipher, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $tag);
}
Anahtar veritabanında DEĞİL, ENV değişkende veya KMS (Key Management Service) içinde tutulur. DB ele geçse anahtar elde edilemez.
ModSecurity ve WAF (Web Application Firewall)
cPanel sunucularında ModSecurity otomatik kurulur; OWASP Core Rule Set ile SQL injection, XSS, RFI saldırılarını yakalar.
cPanel'de ModSecurity Kontrol
WHM > Security Center > ModSecurity Configuration
WHM > Security Center > ModSecurity Vendors
OWASP CRS (Core Rule Set) en yaygın; aktif olduğunu doğrulayın.
Imunify360 (Buyukweb Opsiyonel)
Imunify360 cPanel ek güvenlik servisi: gelişmiş ML tabanlı saldırı tespiti, malware tarama, brute-force koruma. Buyukweb'de paket eki olarak satın alınabilir.
Backup ve Test Restore
Güvenlik = "saldırı olmasın" değil; "saldırı olduğunda kurtul". Yedek olmadan güvenlik yok.
cPanel JetBackup
Buyukweb cPanel paketlerinde günlük 7-gün + haftalık 4-hafta JetBackup standart. Tek-tıkla restore.
Manuel mysqldump (VDS)
# Cron — günlük yedek
0 3 * * * mysqldump --single-transaction -u backupuser -p'PASS' wp_buyukweb \
| gzip > /backup/wp-$(date +\%F).sql.gz
# 30 günden eski yedekleri sil
find /backup -name "wp-*.sql.gz" -mtime +30 -delete
Test Restore
Yedeği almak yetmez; yedeği kurtaracak prosedürü test et. Aylık bir kez:
# Test ortamına restore
gunzip < /backup/wp-2026-05-01.sql.gz | mysql -u root -p test_restore_db
Restore başarısızsa şu anda öğrenmek tek seçenek. Kriz anında öğrenmeyin.
Audit Logging
Kim, ne zaman, hangi tabloya, hangi sorguyu attı? MariaDB Audit Plugin:
# MariaDB Audit Plugin kurulum
sudo mysql -u root -p
INSTALL SONAME 'server_audit';
SET GLOBAL server_audit_logging = ON;
SET GLOBAL server_audit_events = 'CONNECT,QUERY,TABLE';
SET GLOBAL server_audit_file_path = '/var/log/mysql/audit.log';
Loglar /var/log/mysql/audit.log dosyasına yazılır; analiz için grep veya log-aggregation tool (Loki, Elastic).
Yaygın Veritabanı Güvenlik Hataları
Hata 1: Default port (3306) public açık
→ bind-address = 127.0.0.1 ve firewall
Hata 2: Web app root user kullanıyor
→ Her app için ayrı user, en az yetki
Hata 3: Parola "password123" veya boş
→ Strong policy + 16+ karakter
Hata 4: Test/staging DB prod ile aynı sunucu
→ Ayır; staging compromise olursa prod'a ulaşmasın
Hata 5: SQL query string concat ile inşa
→ Prepared statement / ORM zorunlu
Hata 6: WordPress kurulumda root user
→ Kurulum sonrası dedicated user oluştur, root'u bağlama
Hata 7: Backup parolası DB'de
→ Anahtarı dış sistemde tut (KMS, Vault, ENV)
Hata 8: CDN bypass — public IP biliniyorsa
→ CloudFlare Origin Cert + Authenticated Origin Pulls
Sık Sorulan Sorular
Buyukweb cPanel'de SQL injection koruması var mı?
Sunucu seviyesinde ModSecurity + OWASP CRS otomatik aktif; yaygın injection pattern'lerini engeller. Imunify360 (opsiyonel) ek ML-tabanlı koruma sağlar. Ama kod seviyesi koruma müşteri sorumluluğunda — prepared statement kullanmazsanız sunucu koruması her saldırıyı yakalayamaz.
WordPress kullanıcısıyım, ne yapmalıyım?
WordPress core ve eklentiler 2026'da prepared statement standardı; modern kod genelde güvenli. Asıl risk:
- Eski/mahbet eklentiler — kullanmıyorsanız silin (deactivate yetmez)
- Eski PHP versiyonu — PHP 8.1+ kullanın
- Default DB prefix
wp_— kurulumdawp_xyz123_gibi rastgele prefix - wp-config.php izinleri —
chmod 600 wp-config.php - Wordfence veya iThemes Security — güvenlik eklentisi
"SQL Injection saldırı denedim, hata 403 aldım" — koruma mı?
Evet, ModSecurity yakaladı. Loga bak: /usr/local/apache/logs/error_log veya /var/log/modsec_audit.log — saldırı pattern'i görünür. Sevin ama kod seviyesi koruma da uygulayın.
MySQL audit log alan tüketir mi?
Evet, çok aktif sunucu günde GB seviyesi log üretir. logrotate ile haftalık rotate + sıkıştırma + 30 gün retention politikası kurun. Audit log'u sadece gerekli olaylarla sınırlayın (CONNECT yerine sadece TABLE değişikliği).
MariaDB üzerinde "ROW level security" var mı?
PostgreSQL'de var; MariaDB 10.6'da sınırlı (view + GRANT kombosuyla simüle edilir). Müşteri-bazlı veri izolasyonu gerekiyorsa application-level filtering veya tenant column.
KVKK için DB şifrelemesi zorunlu mu?
KVKK kişisel veri için uygun teknik tedbir zorunlu kılıyor; spesifik şifreleme yöntemi belirtmiyor. Uygulama-seviyesi şifreleme (TC, telefon, kart) + DB-seviyesi disk şifreleme (LUKS, transparent encryption) kombo iyi pratik.
"DB'ye SSL gerek yok, localhost kullanıyorum" doğru mu?
Doğru — UNIX socket bağlantısı zaten şifresiz ama lokal. Sadece TCP localhost'da bile küçük performans cost'u var. Gerçek senaryo: web ve DB farklı sunuculardaysa SSL kesinlikle gerekli.
Backup'ı bulut depoya almak güvenli mi?
Evet ama şifreleyerek. gpg veya age ile yedek dosyasını şifreleyin, sonra S3/Backblaze B2/Wasabi'ye yükleyin. Anahtar bulutta olmamalı; anahtarı kaybedersiniz yedeği açamazsınız (yedek-yedek!).
"Veritabanı parolasını .env dosyasında tutuyorum" güvenli mi?
.env dosyası doğru izinlerde (chmod 600) ve git'e commit edilmemiş olmalı. .gitignore listesinde .env zorunlu. CI/CD pipeline'da secrets manager (Vault, GitHub Secrets) kullanın.
Sonuç
Veritabanı güvenliği tek kritik tedbir değil, kademeli savunma: kod (prepared statement) → DB user (en az yetki) → ağ (firewall + bind) → şifreleme (SSL + AES) → audit + backup. Buyukweb cPanel müşterilerimiz için sunucu seviyesi koruma standart; kod seviyesi sorumluluk müşteride. WordPress kullanıyorsanız modern eklenti + dedicated DB user + Wordfence kombinasyonu yeterli. Custom uygulamalarda OWASP Top 10'u baştan sona uygulayın. Backup test restore prosedürü en az ayda bir.
Soru ve teknik destek için: 0850 302 60 70.
İlgili Büyükweb Hizmetleri
DB güvenliği için altyapı paketleri:
- cPanel Web Hosting — ModSecurity standart
- WordPress Hosting — WP optimize güvenlik
- VDS Sunucu — özel DB sunucu, SSL/audit kontrolü
- E5 v4 VDS — yüksek IOPS NVMe
- Tüm Paketler — Karşılaştırma
Sorularınız için 0850 302 60 70 numaralı destek hattımıza veya iletişim sayfamıza yazabilirsiniz.
Veritabanı Yönetimi İlgili Hizmetlerimiz
Bu yazıda anlatılan teknik konuyu profesyonel altyapıyla deneyimleyin
Etiketler:

