Buyukweb
Veritabanı Güvenliği: SQL Injection Önleme ve Erişim Kontrolü

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.

Büyükweb Editör EkibiHosting, Sunucu ve Sistem Yönetimi Editörü10 dakika okuma

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:

  1. Eski/mahbet eklentiler — kullanmıyorsanız silin (deactivate yetmez)
  2. Eski PHP versiyonu — PHP 8.1+ kullanın
  3. Default DB prefix wp_ — kurulumda wp_xyz123_ gibi rastgele prefix
  4. wp-config.php izinlerichmod 600 wp-config.php
  5. 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:

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:

#veritabanı#database#veri yönetimi

Bu yazıyı paylaş