WordPress Login Sayfasında Hata Mesajlarını Gizleme
Bir WordPress sitesi kurduğunuzda, varsayılan olarak gelen login hata mesajları aslında saldırganlara çok değerli bilgiler sağlar. “Kullanıcı adı yanlış” veya “Şifre hatalı” gibi mesajlar, kötü niyetli kişilerin hangi bilgiyi doğru tahmin ettiklerini anlamalarına yardımcı olur. Bu yazıda, WordPress login güvenliğini artırmak için hata mesajlarını nasıl gizleyeceğimizi, özelleştireceğimizi ve bu işlemleri functions.php üzerinden nasıl yöneteceğimizi ele alacağız.
Neden Hata Mesajları Tehlikelidir?
WordPress’in varsayılan davranışını düşünelim. Bir kullanıcı yanlış kullanıcı adı girdiğinde ekranda şunu görür: “admin adlı bir kullanıcı bulunamadı.” Eğer kullanıcı adını doğru girip şifreyi yanlış girerse bu sefer şu mesaj çıkar: “admin için girdiğiniz şifre hatalı.”
Bu iki farklı mesaj, bir brute force saldırısı yapan kişiye altın değerinde bilgi verir. Saldırgan şunu anlar: “Kullanıcı adını buldum, artık sadece şifreyi kırmam gerekiyor.” Bu bilgiyle saldırı vektörü yarıya iner ve hedefli bir şifre deneme saldırısı başlatabilir.
Gerçek dünyadan bir örnek verelim: Küçük bir e-ticaret sitesi yönetiyorsunuz, WooCommerce kurulu, müşteri verileri mevcut. Saldırgan önce admin, administrator, info, shop gibi yaygın kullanıcı adlarını deniyor. WordPress her seferinde “bu kullanıcı bulunamadı” diyerek hangisinin var hangisinin olmadığını açıklıyor. Doğru kullanıcı adını bulduktan sonra wordlist ile şifre deniyor. İşte bu noktada hata mesajlarını gizlemek kritik bir önlem haline geliyor.
Temel Hata Mesajı Gizleme
İlk ve en temel adım, login_errors filtresini kullanarak tüm hata mesajlarını genel bir mesajla değiştirmektir. Bu kod, functions.php dosyanıza eklendiğinde hem kullanıcı adı hem de şifre hatalarını aynı genel mesajla gösterir.
// wp-content/themes/your-theme/functions.php
function guvenli_login_hata_mesaji() {
return 'Giriş bilgileriniz hatalı. Lütfen tekrar deneyiniz.';
}
add_filter( 'login_errors', 'guvenli_login_hata_mesaji' );
Bu tek satırlık çözüm bile büyük bir güvenlik açığını kapatır. Artık saldırgan kullanıcı adının var olup olmadığını bilemez. Ama bu sadece başlangıç, daha kapsamlı bir koruma için devam edelim.
Login Hint Mesajlarını Kaldırma
WordPress’in bir diğer bilgi sızdıran özelliği “hint” mesajlarıdır. Şifre sıfırlama formunda veya login sayfasında bazen kullanıcıya ipucu niteliğinde mesajlar gösterilir. Bunları da kapatmak gerekir.
// Hint mesajlarını kaldır
function login_hint_kaldir( $error ) {
// Kullanici adi ipucunu kaldir
if ( strpos( $error, 'kullanıcı adı' ) !== false ||
strpos( $error, 'username' ) !== false ) {
return 'Giriş bilgileriniz hatalı.';
}
// Sifre ipucunu kaldir
if ( strpos( $error, 'şifre' ) !== false ||
strpos( $error, 'password' ) !== false ) {
return 'Giriş bilgileriniz hatalı.';
}
// E-posta ile ilgili ipucunu kaldir
if ( strpos( $error, 'e-posta' ) !== false ||
strpos( $error, 'email' ) !== false ) {
return 'Giriş bilgileriniz hatalı.';
}
return $error;
}
add_filter( 'login_errors', 'login_hint_kaldir' );
Bu yaklaşım, hata mesajının içeriğini analiz ederek kategorilere ayırır ve hepsini aynı genel mesajla değiştirir. Dil desteği için hem Türkçe hem İngilizce kontrol eklediğimize dikkat edin, çünkü WordPress dil paketine göre farklı mesajlar üretebilir.
Brute Force Koruması: Deneme Sayısını Sınırlama
Hata mesajlarını gizlemek tek başına yeterli değildir. Buna ek olarak belirli bir IP adresinden yapılan başarısız giriş denemelerini sayıp sınırlandırmak gerekir. Bu işlemi WordPress transient API’si kullanarak yapabiliriz.
// Basarisiz giris denemelerini say ve IP bazli kilitle
function brute_force_korumasi( $user, $username, $password ) {
if ( empty( $username ) ) {
return $user;
}
$ip_adresi = $_SERVER['REMOTE_ADDR'];
$transient_key = 'login_attempt_' . md5( $ip_adresi );
$max_deneme = 5;
$bekleme_suresi = 15 * MINUTE_IN_SECONDS; // 15 dakika
$deneme_sayisi = get_transient( $transient_key );
if ( $deneme_sayisi === false ) {
$deneme_sayisi = 0;
}
// Maksimum deneme asildiysa engelle
if ( (int) $deneme_sayisi >= $max_deneme ) {
return new WP_Error(
'too_many_attempts',
'Çok fazla başarısız giriş denemesi. Lütfen 15 dakika bekleyiniz.'
);
}
return $user;
}
add_filter( 'authenticate', 'brute_force_korumasi', 30, 3 );
// Basarisiz giriste sayaci artir
function basarisiz_giris_say() {
$ip_adresi = $_SERVER['REMOTE_ADDR'];
$transient_key = 'login_attempt_' . md5( $ip_adresi );
$bekleme_suresi = 15 * MINUTE_IN_SECONDS;
$deneme_sayisi = get_transient( $transient_key );
if ( $deneme_sayisi === false ) {
set_transient( $transient_key, 1, $bekleme_suresi );
} else {
set_transient( $transient_key, (int) $deneme_sayisi + 1, $bekleme_suresi );
}
}
add_action( 'wp_login_failed', 'basarisiz_giris_say' );
// Basarili giriste sayaci sifirla
function basarili_giris_sifirla( $user_login ) {
$ip_adresi = $_SERVER['REMOTE_ADDR'];
$transient_key = 'login_attempt_' . md5( $ip_adresi );
delete_transient( $transient_key );
}
add_action( 'wp_login', 'basarili_giris_sifirla' );
Bu kod bloğu üç ayrı hook kullanır. authenticate filtresi giriş denemesini doğrulamadan önce çalışır, wp_login_failed başarısız girişlerde tetiklenir, wp_login ise başarılı girişlerde sayacı temizler. Böylece meşru kullanıcılar başarıyla giriş yaptıklarında kilitlenme durumu ortadan kalkar.
Kullanıcı Adı Enumeration Koruması
WordPress’te kullanıcı adları birden fazla yoldan keşfedilebilir. Login sayfası dışında /?author=1 gibi URL parametreleri veya REST API üzerinden de kullanıcı adları açığa çıkabilir. Bu güvenlik açığını kapatalım.
// Yazar sayfasindan kullanici adi ifsa olmasi
function yazar_enumeration_engelle() {
if ( ! is_admin() && isset( $_GET['author'] ) ) {
// Yazar parametresi varsa ana sayfaya yonlendir
if ( is_numeric( $_GET['author'] ) ) {
wp_redirect( home_url(), 301 );
exit;
}
}
}
add_action( 'init', 'yazar_enumeration_engelle' );
// REST API uzerinden kullanici bilgisi ifsa olmasi
function rest_api_kullanici_gizle( $endpoints ) {
if ( isset( $endpoints['/wp/v2/users'] ) ) {
foreach ( $endpoints['/wp/v2/users'] as $key => $endpoint_data ) {
if ( ! current_user_can( 'list_users' ) ) {
$endpoints['/wp/v2/users'][ $key ]['permission_callback'] = function() {
return new WP_Error(
'rest_forbidden',
'Bu endpoint erişime kapalıdır.',
array( 'status' => 403 )
);
};
}
}
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[d]+)'] ) ) {
foreach ( $endpoints['/wp/v2/users/(?P<id>[d]+)'] as $key => $endpoint_data ) {
if ( ! current_user_can( 'list_users' ) ) {
$endpoints['/wp/v2/users/(?P<id>[d]+)'][ $key ]['permission_callback'] = function() {
return new WP_Error(
'rest_forbidden',
'Bu endpoint erişime kapalıdır.',
array( 'status' => 403 )
);
};
}
}
}
return $endpoints;
}
add_filter( 'rest_endpoints', 'rest_api_kullanici_gizle' );
Bu iki fonksiyon farklı vektörleri kapatır. Birincisi /?author=1 gibi URL parametrelerini engeller, ikincisi ise REST API üzerinden kullanıcı listesinin çekilmesini yetkisiz kullanıcılara kapatır.
WooCommerce Login Sayfası İçin Özel Koruma
WooCommerce çalıştırıyorsanız müşteri hesabı giriş sayfası /my-account/ altında ayrı bir login formu daha bulunur. Bu formun da aynı güvenlik önlemlerine ihtiyacı var.
// WooCommerce giris hata mesajlarini ozellestir
function woocommerce_login_hata_ozellestir( $messages ) {
$genel_mesaj = array(
'error' => array(
'Giriş bilgileriniz hatalı. Lütfen tekrar deneyiniz veya şifrenizi sıfırlayınız.'
)
);
// Orijinal mesajlarda hassas bilgi var mi kontrol et
if ( isset( $messages['error'] ) ) {
foreach ( $messages['error'] as $mesaj ) {
// Kullanici adi veya sifre ile ilgili spesifik mesajlari genel mesajla degistir
if ( strpos( $mesaj, 'bilinmiyor' ) !== false ||
strpos( $mesaj, 'yanlış' ) !== false ||
strpos( $mesaj, 'hatalı' ) !== false ||
strpos( $mesaj, 'bulunamadı' ) !== false ) {
return $genel_mesaj;
}
}
}
return $messages;
}
add_filter( 'woocommerce_login_form_error_messages', 'woocommerce_login_hata_ozellestir' );
// WooCommerce icin de deneme sinirlamasi
function woocommerce_brute_force_kontrol() {
if ( isset( $_POST['login'] ) && isset( $_POST['username'] ) ) {
$ip_adresi = $_SERVER['REMOTE_ADDR'];
$transient_key = 'wc_login_attempt_' . md5( $ip_adresi );
$deneme_sayisi = get_transient( $transient_key );
if ( $deneme_sayisi !== false && (int) $deneme_sayisi >= 5 ) {
wc_add_notice(
'Çok fazla başarısız giriş denemesi. Lütfen 15 dakika bekleyin.',
'error'
);
return;
}
}
}
add_action( 'woocommerce_before_customer_login_form', 'woocommerce_brute_force_kontrol' );
WooCommerce’in kendi notice sistemi olduğu için wc_add_notice() fonksiyonunu kullanıyoruz. Bu, WooCommerce tema yapısıyla uyumlu çalışır ve hata mesajı doğru şekilde görüntülenir.
Şifre Sıfırlama Formunda Bilgi Sızdırma
Çoğu sysadmin login sayfasını sıkılaştırmayı düşünür ama şifre sıfırlama formunu unutur. WordPress’in varsayılan şifre sıfırlama formu da hassas bilgi sızdırabilir. “Bu e-posta adresiyle kayıtlı kullanıcı bulunamadı” gibi mesajlar, bir saldırganın hangi e-posta adreslerinin sistemde kayıtlı olduğunu anlamasına yardımcı olur.
// Sifre sifirlama formundaki bilgi ifsa mesajlarini gizle
function sifre_sifirlama_mesaj_gizle( $errors, $user_data ) {
// Kullanici bulunamadi hatasini genel mesajla degistir
if ( $errors->get_error_code() === 'invalidcombo' ||
$errors->get_error_code() === 'invalid_email' ||
$errors->get_error_code() === 'invalidkey' ) {
return new WP_Error(
'reset_error',
'Girdiğiniz bilgiler için bir sıfırlama bağlantısı gönderilemedi. Lütfen bilgilerinizi kontrol ediniz.'
);
}
return $errors;
}
add_filter( 'lostpassword_errors', 'sifre_sifirlama_mesaj_gizle', 10, 2 );
// Sifre sifirlama basarili mesajini da ozellestir
function sifre_sifirlama_basarili_mesaj( $message ) {
return 'Eğer bu e-posta adresine kayıtlı bir hesap varsa, kısa süre içinde sıfırlama bağlantısı gönderilecektir.';
}
add_filter( 'retrieve_password_message', 'sifre_sifirlama_basarili_mesaj' );
Burada dikkat edilmesi gereken önemli bir nokta var. Başarılı mesajı da belirsizleştiriyoruz. “E-posta gönderildi” yerine “eğer böyle bir hesap varsa gönderilecektir” diyoruz. Bu yaklaşım, saldırganın e-posta adresini doğrulamasını engeller.
Giriş Denemelerini Loglama
Güvenlik olaylarını takip etmek için başarısız giriş denemelerini bir log dosyasına veya veritabanına kaydetmek iyi bir pratiktir. Böylece hangi IP adreslerinin sistemi zorladığını görebilir ve gerekirse sunucu tarafında kalıcı engelleme yapabilirsiniz.
// Basarisiz giris denemelerini logla
function login_denemelerini_logla( $username ) {
$ip_adresi = $_SERVER['REMOTE_ADDR'];
$zaman = current_time( 'mysql' );
$user_agent = isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] ) : 'Bilinmiyor';
// Hassas bilgi saklamamak icin kullanici adini kisalt veya hash'le
$kullanici_hash = md5( strtolower( trim( $username ) ) );
$log_verisi = array(
'ip' => $ip_adresi,
'zaman' => $zaman,
'user_hash' => $kullanici_hash,
'user_agent' => substr( $user_agent, 0, 200 ),
);
// WordPress options tablosuna yaz (kucuk siteler icin)
$mevcut_log = get_option( 'guvenlik_login_log', array() );
// Son 1000 kaydi tut, eskilerini sil
if ( count( $mevcut_log ) >= 1000 ) {
$mevcut_log = array_slice( $mevcut_log, -999, 999, true );
}
$mevcut_log[] = $log_verisi;
update_option( 'guvenlik_login_log', $mevcut_log, false );
// Eger WP_DEBUG aktifse error log'a da yaz
if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
error_log( sprintf(
'[GUVENLIK] Basarisiz giris: IP=%s, Hash=%s, Zaman=%s',
$ip_adresi,
$kullanici_hash,
$zaman
) );
}
}
add_action( 'wp_login_failed', 'login_denemelerini_logla' );
// Log verisini admin panelinde goruntule (basit widget)
function login_log_admin_widget() {
$mevcut_log = get_option( 'guvenlik_login_log', array() );
$son_kayitlar = array_slice( $mevcut_log, -10 );
$son_kayitlar = array_reverse( $son_kayitlar );
echo '<h3>Son Başarısız Giriş Denemeleri</h3>';
echo '<ul>';
foreach ( $son_kayitlar as $kayit ) {
echo '<li>' . esc_html( $kayit['zaman'] ) . ' - IP: ' . esc_html( $kayit['ip'] ) . '</li>';
}
echo '</ul>';
}
Dikkat etmeniz gereken önemli bir GDPR/KVKK nüansı: kullanıcı adlarını doğrudan loglamak yerine hash’liyoruz. Bu hem güvenlik hem de veri gizliliği açısından doğru yaklaşımdır. IP adresi de kişisel veri sayılabilir, bu yüzden log saklama sürenizi gizlilik politikanıza göre ayarlamanız gerekir.
XML-RPC Üzerinden Giriş Koruması
Birçok sysadmin bunu atlar: XML-RPC, WordPress’in neredeyse unutulmuş bir özelliğidir ama hala aktif ve brute force saldırıları için kullanılır. Özellikle system.multicall metodu aracılığıyla tek bir istekte yüzlerce kullanıcı adı/şifre kombinasyonu denenebilir.
// XML-RPC'yi tamamen devre disi birak (eger kullanmiyorsaniz)
add_filter( 'xmlrpc_enabled', '__return_false' );
// Ya da sadece belirli metodlari engelle
function xmlrpc_metod_kisitla( $methods ) {
// Brute force icin kullanilan metodlari kaldir
unset( $methods['system.multicall'] );
unset( $methods['system.listMethods'] );
unset( $methods['system.getCapabilities'] );
return $methods;
}
add_filter( 'xmlrpc_methods', 'xmlrpc_metod_kisitla' );
// XML-RPC giris hata mesajlarini da gizle
function xmlrpc_hata_mesaji_gizle( $error ) {
if ( is_wp_error( $error ) ) {
$error_codes = array(
'incorrect_password',
'invalid_username',
'authentication_error'
);
if ( in_array( $error->get_error_code(), $error_codes ) ) {
return new WP_Error(
'auth_failed',
'Kimlik doğrulama başarısız.',
array( 'status' => 403 )
);
}
}
return $error;
}
add_filter( 'xmlrpc_login_error', 'xmlrpc_hata_mesaji_gizle' );
Eğer Jetpack, WordPress mobil uygulaması veya harici araçlar kullanmıyorsanız XML-RPC’yi tamamen kapatmak en güvenli seçenektir. add_filter( 'xmlrpc_enabled', '__return_false' ) tek satırla bunu halleder.
Güvenlik Başlıkları ile Destekleme
functions.php üzerinden login güvenliğini HTTP başlıkları ile de destekleyebilirsiniz. Bu başlıklar, tarayıcı tabanlı saldırılara karşı ek bir koruma katmanı sağlar.
// Login sayfasina guvenlik basliklari ekle
function login_guvenlik_basliklari() {
if ( $GLOBALS['pagenow'] === 'wp-login.php' ) {
// Clickjacking koruması
header( 'X-Frame-Options: DENY' );
// XSS koruması (eski tarayıcılar için)
header( 'X-XSS-Protection: 1; mode=block' );
// MIME sniffing koruması
header( 'X-Content-Type-Options: nosniff' );
// Referrer politikası
header( 'Referrer-Policy: no-referrer' );
// Cache kontrol - login sayfasi cacheklenmemeli
header( 'Cache-Control: no-store, no-cache, must-revalidate, max-age=0' );
header( 'Pragma: no-cache' );
}
}
add_action( 'login_init', 'login_guvenlik_basliklari' );
Bu başlıklar özellikle wp-login.php sayfasına uygulanır. Cache başlıkları da ekledik çünkü login sayfasının bir CDN veya proxy tarafından önbelleğe alınması ciddi güvenlik sorunlarına yol açabilir.
Tüm Fonksiyonları Bir Arada Kullanma
Yukarıdaki tüm kodları ayrı ayrı kopyalamak yerine, bunları organize bir şekilde bir araya getirmek daha temiz bir yaklaşımdır. Aşağıda tüm fonksiyonları tek bir yapıda topladık:
/**
* Login Guvenlik Sinifi
* Tum login guvenlik onlemlerini bir arada toplar
*/
class WP_Login_Guvenligi {
private static $max_deneme = 5;
private static $bekleme_sure = 900; // 15 dakika saniye cinsinden
public static function baslat() {
// Hata mesajlarini gizle
add_filter( 'login_errors', array( __CLASS__, 'hata_mesaji_gizle' ) );
// Brute force korumasi
add_filter( 'authenticate', array( __CLASS__, 'brute_force_kontrol' ), 30, 3 );
add_action( 'wp_login_failed', array( __CLASS__, 'basarisiz_giris' ) );
add_action( 'wp_login', array( __CLASS__, 'basarili_giris' ) );
// Kullanici enumeration
add_action( 'init', array( __CLASS__, 'enumeration_engelle' ) );
add_filter( 'rest_endpoints', array( __CLASS__, 'rest_kullanici_gizle' ) );
// Sifre sifirlama
add_filter( 'lostpassword_errors', array( __CLASS__, 'sifre_sifirlama_gizle' ), 10, 2 );
// XML-RPC
add_filter( 'xmlrpc_enabled', '__return_false' );
// Guvenlik basliklari
add_action( 'login_init', array( __CLASS__, 'guvenlik_basliklari' ) );
}
public static function hata_mesaji_gizle() {
return 'Giriş bilgileriniz hatalı. Lütfen tekrar deneyiniz.';
}
public static function brute_force_kontrol( $user, $username, $password ) {
if ( empty( $username ) ) return $user;
$key = 'lga_' . md5( $_SERVER['REMOTE_ADDR'] );
$deneme = get_transient( $key );
if ( $deneme !== false && (int) $deneme >= self::$max_deneme ) {
return new WP_Error( 'cok_fazla_deneme', 'Çok fazla başarısız deneme. Lütfen bekleyiniz.' );
}
return $user;
}
public static function basarisiz_giris() {
$key = 'lga_' . md5( $_SERVER['REMOTE_ADDR'] );
$deneme = get_transient( $key );
$deneme = ( $deneme === false ) ? 1 : (int) $deneme + 1;
set_transient( $key, $deneme, self::$bekleme_sure );
}
public static function basarili_giris() {
delete_transient( 'lga_' . md5( $_SERVER['REMOTE_ADDR'] ) );
}
public static function enumeration_engelle() {
if ( ! is_admin() && isset( $_GET['author'] ) && is_numeric( $_GET['author'] ) ) {
wp_redirect( home_url(), 301 );
exit;
}
}
public static function rest_kullanici_gizle( $endpoints ) {
if ( ! current_user_can( 'list_users' ) ) {
unset( $endpoints['/wp/v2/users'] );
unset( $endpoints['/wp/v2/users/(?P<id>[d]+)'] );
}
return $endpoints;
}
public static function sifre_sifirlama_gizle( $errors ) {
return new WP_Error(
'reset_error',
'Girdiğiniz bilgiler için işlem gerçekleştirilemedi.'
);
}
public static function guvenlik_basliklari() {
header( 'X-Frame-Options: DENY' );
header( 'X-Content-Type-Options: nosniff' );
header( 'Cache-Control: no-store, no-cache' );
}
}
// Sinifi baslat
WP_Login_Guvenligi::baslat();
Nesne yönelimli bu yapı, fonksiyonların global namespace’i kirletmesini önler ve tüm güvenlik kodunu tek bir yerde yönetmenizi sağlar. Bir ayarı değiştirmek için tek bir sınıf özelliğini güncellemeniz yeterlidir.
Dikkat Edilmesi Gereken Noktalar
Bu güvenlik önlemlerini uygularken bazı pratik noktalara dikkat etmek gerekir:
- Çocuk tema kullanımı: Bu kodları doğrudan ana temanın
functions.phpdosyasına eklemek, tema güncellemelerinde kodların silinmesine neden olur. Her zaman çocuk tema oluşturun ve oraya ekleyin.
- Transient temizliği: Brute force koruması için kullandığımız transient’lar veritabanında birikebilir. WordPress cron job’ları bunları otomatik temizler ama büyük sitelerde performans etkisi olabilir. Object cache (Redis/Memcached) kullanıyorsanız transient’lar orada saklanır, veritabanı yükü azalır.
- Güvenilir IP adresleri:
$_SERVER['REMOTE_ADDR']bazen proxy veya yük dengeleyici IP adresini döndürebilir. Sunucu yapılandırmanıza göreHTTP_X_FORWARDED_FORbaşlığını da değerlendirmeniz gerekebilir. Ancak bu başlık sahte olabileceği için dikkatli kullanın.
- Meşru kullanıcıların kilitlenmesi: Brute force koruması aşırı agresif ayarlandığında meşru kullanıcılar kilitlenebilir. 5 deneme ve 15 dakika bekleme genellikle iyi bir denge sağlar, ama ihtiyacınıza göre ayarlayın.
- Eklenti çakışmaları: Wordfence, iThemes Security gibi güvenlik eklentileri zaten benzer fonksiyonlar içerir. Bu kodları bu eklentilerle birlikte kullanırsanız çakışma ve çift engelleme durumları yaşanabilir. Bu yüzden ya eklenti kullanın ya da bu kodları manuel ekleyin, ikisini birden yapmaktan kaçının.
Sonuç
WordPress login güvenliği tek bir önlemle sağlanamaz, katmanlı bir yaklaşım gerektirir. Hata mesajlarını gizlemek bu katmanlardan sadece biridir. Bununla birlikte brute force koruması, kullanıcı adı enumeration engeli, şifre sıfırlama formunun güvenliği ve XML-RPC kontrolü uygulandığında ciddi bir güvenlik seviyesine ulaşılır.
Gerçek dünyada bu önlemleri uygulayan bir WooCommerce sitesinde, sunucu log analizi yapıldığında brute force denemelerinin dramatik biçimde düştüğü görülür. Saldırganlar standart araçlarla kolayca geçilemeyen bir hedef gördüklerinde genellikle daha kolay hedeflere yönelir.
Son olarak şunu hatırlatmak gerekir: Bu kodlar güvenliği artırır ama %100 koruma sağlamaz. Güçlü şifre politikaları, iki faktörlü kimlik doğrulama, düzenli güncellemeler ve sunucu tarafı güvenlik önlemleri (fail2ban, Cloudflare gibi WAF çözümleri) bu kodları tamamlayan diğer önemli unsurlardır. Güvenlik bir son nokta değil, sürekli devam eden bir süreçtir.
