Ana Sayfa / Blog / WordPress güvenlik sertleştirme: .htaccess’ten mu-plugins’e

WordPress güvenlik sertleştirme: .htaccess’ten mu-plugins’e

WordPress default kurulum hedef tahtası. Beş katman halinde uyguladığım sertleştirme pratiklerini, hangi saldırıya karşı neyi yaptığımı paylaştım.

Bir müşterinin sitesi hack’lendi, temiz kurulum yaptıktan sonra aynı gün yine hack oldu. Logları incelediğimde gördüm, saldırı vektörü wp-login.php brute force idi. Temiz kurulum yapmakla yetinilmez, savunma katmanları gerekiyor. O günden sonra kurduğum her sitede aynı sertleştirmeyi uyguluyorum. Katman katman paylaşayım.

Katman 1: web server (.htaccess / nginx)

İlk savunma isteklerin uygulamaya ulaşmadan önce filtrelenmesi.

# wp-config.php gizle
<Files wp-config.php>
  Require all denied
</Files>

# xmlrpc.php engelle (pingback ve brute force saldırı hedefi)
<Files xmlrpc.php>
  Require all denied
</Files>

# php dosyalarının upload klasöründe çalışmasını engelle
<Directory "wp-content/uploads">
  <FilesMatch "\.(php|phtml|phar)$">
    Require all denied
  </FilesMatch>
</Directory>

# user enumeration engelle (?author=1)
RewriteCond %{QUERY_STRING} author=\d
RewriteRule ^ - [L,R=403]

# readme.html gizle (WP version sızdırır)
<Files readme.html>
  Require all denied
</Files>

Nginx için eşdeğerleri location block’larında.

Katman 2: wp-config.php

WordPress’in kendi ayar dosyası. Birkaç sabit şart:

// dosya düzenlemeyi kapat (tema/plugin editörü)
define('DISALLOW_FILE_EDIT', true);

// plugin/theme install/update admin'den de kapalı olsun (CI/CD ile yapılsın)
define('DISALLOW_FILE_MODS', true);

// database'e verilen hata mesajlarını debug.log'a yönlendir
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

// auth key'ler üretilmiş olmalı (wp-cli ile)
// https://api.wordpress.org/secret-key/1.1/salt/ adresinden güncel set

// force SSL admin
define('FORCE_SSL_ADMIN', true);

// autosave ve revisions sınırla
define('WP_POST_REVISIONS', 5);

DISALLOW_FILE_MODS kritik, birisi admin’e girse bile plugin kuramaz. Yeni plugin WP-CLI veya deployment pipeline ile yüklenir.

Katman 3: mu-plugins

must-use plugins, deactivate edilemiyor. Güvenlik kontrolleri için ideal.

Bu temada [wp-content/mu-plugins/ac-security-hardening.php](wp-content/mu-plugins/ac-security-hardening.php) var, içinde:

  • REST API /users endpoint’ini authenticated olmayan için kapatıyor.
  • X-Powered-By, Server header’larını kaldırıyor.
  • Application passwords’u kısıtlıyor.
  • Login başarısız olunca log’luyor (fail2ban entegrasyonu için).
  • wp-json/oembed endpoint’lerini sertleştiriyor.
  • pingback (XMLRPC) servislerini kaldırıyor.
// rest api user enumeration engelle
add_filter('rest_endpoints', function ($endpoints) {
    if (isset($endpoints['/wp/v2/users'])) unset($endpoints['/wp/v2/users']);
    if (isset($endpoints['/wp/v2/users/(?P<id>[\d]+)'])) unset($endpoints['/wp/v2/users/(?P<id>[\d]+)']);
    return $endpoints;
});

// basarisiz login'i logla
add_action('wp_login_failed', function ($username) {
    error_log(sprintf('[LOGIN_FAIL] %s from %s', $username, $_SERVER['REMOTE_ADDR']));
});

// login endpoint'ini rate limit
add_action('login_form_login', function () {
    $ip = $_SERVER['REMOTE_ADDR'];
    $key = 'ac_login_attempts_' . md5($ip);
    $attempts = get_transient($key) ?: 0;
    if ($attempts >= 5) wp_die('Çok fazla deneme yaptınız. 15 dakika sonra tekrar deneyin.', 429);
    set_transient($key, $attempts + 1, 15 * MINUTE_IN_SECONDS);
});

Katman 4: kullanıcı disiplini

  • Admin kullanıcı adı “admin” olmamalı. Brute force bu hedefi bulur.
  • Strong password zorunluluğu.
  • Two-factor authentication plugin’i (ama iki TOTP kabul eden yetki). Admin kullanıcılarda şart.
  • Düzenli parola rotasyonu. 6 ayda bir.
  • Kullanılmayan user hesapları silinsin.
  • Plugin role editor ile gerçekten gerekli olan yetkileri verin. Author’a delete_posts veriliyor mu, kontrol edin.

Katman 5: dışardan koruma

  • Cloudflare veya WAF. Bilinen saldırı pattern’larını daha uygulamaya ulaşmadan filtreliyor.
  • Fail2ban ile login log’larından brute force IP’sini ban’lama.
  • SSH key-only access, şifre login kapatılmış olsun.
  • Sunucu düzeyi güncel kernel, up-to-date PHP.
  • Backup. Hack olmuş mu, hemen temiz sürümü geri getirebilmek için.

Hostinger öneri

Bu sitelerde Hostinger’ın kendi security mu-plugin’leri var. hostinger-auto-updates çekirdek güncellemeleri otomatik alıyor. Bunu kapatmayın ama kendi code üstünde tam kontrolünüz olsun.

Test etme

  • WPScan kullanın, kendi sitesine deneme amaçlı çalıştırın.
  • Sucuri sitecheck.sucuri.net ile bakın.
  • Security Headers securityheaders.com üzerinden kontrol. CSP, X-Frame-Options, Referrer-Policy.
  • Düzenli access log inceleme. Anormal pattern’ler (aynı IP’den 500 hit, POST bombardımanı).

Sonuç

Tek bir fix sitenizi güvenli yapmıyor. Katman katman savunma (defense in depth) mantığı gerekiyor. Web server, WordPress config, mu-plugins, kullanıcı yönetimi, dış koruma. Her katman başka bir saldırı vektörünü kapatıyor. Saldırgan birini aşsa bile diğeri duruyor. Mühendislik bu.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç