secaudit.eu
Sıkılaştırma

WordPress kullanıcı numaralandırma: REST API ve yazar URL'leri

WordPress kullanıcı numaralandırma nasıl test edilir: REST API, yazar URL'leri, site haritası ve giriş hatalarından sızan kullanıcı adlarını bulun ve güvenle kapatın.

Yazar: , AngelForce OÜ 5 dk okuma

Diğer diller: English Deutsch Français Español Italiano Polski Português

Varsayılan bir WordPress kurulumunda giriş adlarınızı bulmak genellikle bir dakikadan kısa sürer. WordPress kullanıcı numaralandırma (user enumeration) beş altı yerleşik kanal üzerinden işler: REST API, ?author=1 yönlendirmeleri, yazar arşivi URL'leri, kullanıcı site haritası, giriş hata mesajları ve bazı durumlarda besleme (feed) ile oEmbed verileri. Bu yazıda her kanalı kendi sitenizde nasıl test edeceğinizi ve blok editörünü bozmayan dar kapsamlı düzeltmelerle nasıl kapatacağınızı bulacaksınız.

WordPress kullanıcı numaralandırma nedir, ne kadar önemlidir?

Kullanıcı numaralandırma, bir sitedeki geçerli hesap adlarının toplanması demektir. mkeller hesabının var olduğunu bilen bir saldırgan, tüm parola denemelerini ve başka ihlallerden sızmış parolaları admin, info ya da test gibi tahminler yerine gerçek bir hesap üzerinde harcayabilir.

Adları gizlemenin neyi sağlayıp neyi sağlamadığı konusunda net olun. Bu bir hız kesicidir, koruma değildir. Hesap ele geçirmeyi durduran şey iki faktörlü kimlik doğrulama ve giriş sınırlamasıdır; önce bunları kurun (WordPress için iki faktörlü kimlik doğrulama, kaba kuvvet koruması). Ardından aşağıdaki sızıntıları şu sırayla kapatın: test edin, düzeltin, yeniden test edin.

Şema: WordPress kullanıcı adlarını sızdıran beş kanal ve her birinin çözümü
Kullanıcı adları nereden sızar ve her kanal için dar kapsamlı çözüm

Kendi sitenizi test edin: kullanıcı adlarının sızdığı altı yer

Bu testleri yalnızca sahibi ya da yöneticisi olduğunuz sitelerde çalıştırın. Oturum kapalıyken, bir terminalden veya gizli tarayıcı penceresinden test edin; oturum açık olduğunda çok daha fazlası görünür. example.com yerine kendi alan adınızı yazın.

  1. REST API. Çekirdek (core), içerik yayımlamış kullanıcıları listeler. Yazar slug'ını gösteren slug alanına bakın; bu alan genellikle giriş adıyla aynıdır.
curl -s https://example.com/wp-json/wp/v2/users | grep -o '"slug":"[^"]*"'
curl -s "https://example.com/?rest_route=/wp/v2/users" | grep -o '"slug":"[^"]*"'
  1. Yazar ID yönlendirmeleri. WordPress, ?author=N isteğini okunabilir yazar URL'sine yönlendirir. 1, 2, 3 diye deneyin.
curl -sI "https://example.com/?author=1" | grep -i '^location'
  1. Tema HTML'i. Yazılardaki yazar bağlantıları ve kayıtlı kullanıcıların yorumlarındaki comment-author-<slug> gibi CSS sınıfları.
curl -s https://example.com/a-post/ | grep -oE '/author/[^/"]+/|comment-author-[a-z0-9-]+' | sort -u
  1. Kullanıcı site haritası. Tarayıcıda https://example.com/wp-sitemap-users-1.xml adresini açın.
  1. Giriş hataları. wp-login.php sayfasında önce uydurma bir kullanıcı adı, sonra gerçek bir kullanıcı adı ile yanlış parola girin. Mesajlar farklıysa form geçerli hesapları doğruluyor demektir. Parolamı unuttum formu da aynı şekilde davranır. Kendi sınırlamanız sizi dışarıda bırakmasın diye iki üç denemeyle yetinin.
  1. Beslemeler ve oEmbed. Besleme, görünen adları dc:creator içinde gösterir. oEmbed uç noktası author_name ve author_url döndürür; bu URL yazar slug'ını içerir.
curl -s https://example.com/feed/ | grep -i 'dc:creator'
curl -s "https://example.com/wp-json/oembed/1.0/embed?url=https://example.com/a-post/"
KanalTestNe gösterir
REST kullanıcıları/wp-json/wp/v2/usersSlug, ad, ID
Yazar yönlendirmesi/?author=1Location içinde slug
Tema HTML'iYazı ve yorum işaretlemesiSlug
Kullanıcı site haritası/wp-sitemap-users-1.xmlSlug içeren yazar URL'leri
Giriş hatalarıBilinmeyen kullanıcı / yanlış parolaGeçerli girişler
Besleme / oEmbeddc:creator, author_urlGörünen ad, slug

Yapılandırılmış bir yöntem arıyorsanız OWASP Web Security Testing Guide hesap numaralandırma testlerini daha ayrıntılı ele alır.

REST kullanıcı uç noktasını yalnızca anonim ziyaretçilere kapatın

Yalnızca kullanıcılar rotasını ve yalnızca oturum açmamış istekleri hedefleyin. Blok editörü yazar seçicisi için /wp/v2/users rotasını kullanır; mobil uygulamalar ve birçok eklenti de bu rotayı kimlik doğrulamayla çağırır. Rotayı herkes için kaldırırsanız bunlar çalışmaz.

wp-content/mu-plugins/user-enumeration.php dosyasını oluşturun. Zorunlu eklentiler (must-use plugins) otomatik yüklenir ve panelden devre dışı bırakılamaz. rest_endpoints filtresi, rotaları yanıtlanmadan önce çıkarmanıza olanak tanır:

<?php
/**
 * Plugin Name: Limit user enumeration
 */

add_filter( 'rest_endpoints', function ( $endpoints ) {
    if ( is_user_logged_in() ) {
        return $endpoints;
    }
    unset( $endpoints['/wp/v2/users'] );
    unset( $endpoints['/wp/v2/users/(?P<id>[\d]+)'] );
    return $endpoints;
} );

curl testini yeniden çalıştırın. Şimdi 404 durum kodlu bir rest_no_route hatası görmelisiniz. Ardından oturum açın, bir yazıyı editörde açın ve yazar panelinin kullanıcıları hâlâ listelediğini doğrulayın.

Yazar verisini anonim olarak okuyan bir headless ön yüz ya da uygulama çalıştırıyorsanız bu kod parçası onu bozar. Bu durumda yalnızca ihtiyaç duyduğunuz alanları özel bir uç nokta üzerinden sunun. REST API kullanıcı referansı uç noktanın neler döndürdüğünü listeler.

Yazar ID yönlendirmelerini durdurun, yazar arşivine gerçekten ihtiyacınız olup olmadığına karar verin

Biri /?author=2 isteği yaptığında WordPress kullanıcıyı çözümler ve kanonik yönlendirme ziyaretçiyi /author/<slug>/ adresine gönderir. Location başlığı slug'ı ele verir ve bir betik 1'den 50'ye kadar ID'leri saniyeler içinde tarayabilir.

Bunu, aynı mu-plugin içinde ilk kod parçasının altına ekleyin. Kod, kanonik yönlendirmeden önce çalışır ve author parametreli anonim isteklere düz bir 404 yanıtı verir; böylece slug'ı gösteren bir Location başlığı kalmaz:

add_action( 'template_redirect', function () {
    if ( is_user_logged_in() ) {
        return;
    }
    if ( isset( $_GET['author'] ) ) {
        wp_die( 'Not found.', '', array( 'response' => 404 ) );
    }
}, 1 );

curl -sI "https://example.com/?author=1" ile yeniden test edin. Artık 404 almalı ve Location başlığı görmemelisiniz.

Tek yazarlı bir şirket blogunda ya da herkese açık yazar sayfaları olmayan bir sitede bir adım ileri gidip yazar arşivlerini kapatın. Çoğu SEO eklentisinde, bazı temalarda da bunun için bir ayar bulunur. Sınırı açıkça söyleyelim: temanız her yazıda "yazar: …" bağlantısı basıyorsa slug yine HTML içindedir. Sonraki iki bölüm bununla ilgilenir.

İhtiyaç yoksa kullanıcı site haritasını kaldırın

WordPress 5.5 ile gelen çekirdek site haritaları, her yazar arşivini listeleyen bir kullanıcı sağlayıcısı içerir. Çoğu kurumsal site bundan fayda görmez. wp_sitemaps_add_provider filtresi onu kaldırır:

add_filter( 'wp_sitemaps_add_provider', function ( $provider, $name ) {
    if ( 'users' === $name ) {
        return false;
    }
    return $provider;
}, 10, 2 );

/wp-sitemap-users-1.xml adresini yeniden açın; artık 404 döndürmelidir. Çekirdek site haritalarının yerine bir SEO eklentisi geçtiyse bu filtrenin onun çıktısı üzerinde etkisi olmaz. Eklentinin site haritası ayarlarında yazar site haritası olup olmadığına bakın ve oradan kapatın.

Görünen adları ve yazar slug'larını giriş adlarından farklı yapın

Kullanıcılar > Profil altında bir Takma ad belirleyin ve Herkese açık görünen ad listesinden onu seçin. Bu, beslemeleri, oEmbed author_name değerini ve "yazar:" satırlarını kapsar.

Tuzak şurada: yazar slug'ı (user_nicename) hesap oluşturulurken giriş adından üretilir ve görünen adı değiştirdiğinizde değişmez. Yazılarınızda "Editör ekibi" yazarken URL hâlâ /author/mkeller/ olabilir. WP-CLI ile düzeltin:

wp db export before-nicename.sql
wp user list --fields=ID,user_login,user_nicename,display_name
wp user update 2 --user_nicename=editorial-team

Küçük harf, rakam ve tire kullanın; her slug benzersiz olsun. Eski yazar URL'leri değişir. Bu sayfalar trafik alıyorsa birkaç 404 bekleyin ya da yönlendirme ekleyin.

Yeni hesaplarda admin, şirket adı ve alan adını giriş adı olarak kullanmayın. Eski veya ortak hesaplar sorunun parçasıysa önce onları temizleyin: WordPress kullanıcı rolleri güvenliği.

Genel giriş hata mesajları

login_errors filtresi, giriş ekranında gösterilen mesajları tek bir nötr metinle değiştirir:

add_filter( 'login_errors', function () {
    return '<strong>Error:</strong> The login details are incorrect.';
} );

Bu, boş alan uyarısı gibi yararlı mesajların da yerini alır; kullanıcılarınız daha az yönlendirme alır. Siteyi tamamen opak da yapmaz. Parolamı unuttum formu geçerli hesaplar için hâlâ farklı davranır, çünkü gerçek bir hesap "e-postanızı kontrol edin" ekranına götürür. Bazı eklentiler kendi giriş formlarını ekler ve WooCommerce'in Hesabım sayfasının kendi mesajları vardır. Bunu tutarlılık önlemi olarak görün, güçlü bir kontrol olarak değil.

Kullanıcı adlarını gizlemenin durdurmadığı şeyler

Saldırganlar siteniz sızdırsa da sızdırmasa da yaygın adları ve e-posta adreslerini dener; WordPress da e-posta adresini giriş adı olarak kabul eder. Başka ihlallerden gelen kullanıcı adı ve parola çiftlerini yeniden deneyen kimlik bilgisi doldurma (credential stuffing) saldırısı için numaralandırmaya hiç gerek yoktur. Kusursuzca gizlenmiş bir kullanıcı listesi, yeniden kullanılmış bir parolaya karşı hiçbir işe yaramaz.

Küçük bir kurumsal site için sıra şöyle olmalı:

  1. Her yönetici ve editör için iki faktörlü kimlik doğrulama (kurulum rehberi).
  2. Giriş sınırlaması ve XML-RPC kararı (kaba kuvvet koruması).
  3. Yukarıdaki numaralandırma düzeltmeleri, curl komutlarıyla test edilmiş olarak.
  4. Sonucu düzenli kontrol sürecinize ekleyin (WordPress güvenlik kontrol listesi).

secaudit.eu'nun Security Audit & Compliance eklentisi giriş sınırlaması ve anonim REST istek sınırlaması içerir; sıkılaştırma taraması da yapılandırma bulgularını raporlar, böylece nelerin hâlâ açık olduğunu görebilirsiniz → secaudit.eu

Sonraki adımınız: bu yazıdaki altı testi bugün kendi sitenizde çalıştırın, sonuçları kaydedin ve gerçek bir giriş adı gösteren kanalları düzeltin.

SSS

/wp/v2/users rotasını engellemek blok editörünü bozar mı?

Yukarıdaki kod parçasındaki gibi yalnızca anonim istekleri kısıtlarsanız bozmaz. Editör kimliği doğrulanmış istekler gönderir, bu yüzden yazar seçici çalışmaya devam eder. Rotayı oturum açmış kullanıcılar için de kaldırırsanız bozulur.

2FA varsa "admin" hâlâ risk mi?

Çok daha az. 2FA ile yalnızca tahmin edilen bir parola kimseyi içeri sokmaz. Ancak admin sürekli tahmin denemelerini çeker; bu da günlükleri doldurur ve kilitlenmeleri tetikleyebilir, dolayısıyla yine de değiştirmeye değer.

Giriş adının kendisini yeniden adlandırmalı mıyım, nasıl?

WordPress'te giriş adını değiştiren bir düğme yoktur. Nötr bir giriş adı ve 2FA ile yeni bir yönetici oluşturun, onunla oturum açın, sonra WordPress sorduğunda eski hesabı silip içeriğini yeni hesaba atayın. Her zaman çalışan en az bir yönetici hesabı bulundurun. Ayrıntılar WordPress kullanıcı rolleri güvenliği yazısında.

Kendi sitenizi kontrol edin

Security Audit & Compliance, secaudit.eu’nun WordPress eklentisidir: zararlı yazılımları, gizli spam’i, değiştirilmiş çekirdek dosyalarını ve açıklı kodu tarar; bulguları GDPR Md. 32, NIS2 Md. 21 ve OWASP Top 10 ile eşleştirir.

Eklentinin neleri kontrol ettiğini görün
Melike Görel

Melike Görel, secaudit.eu’nun arkasındaki Tallinn merkezli yazılım şirketi AngelForce OÜ adına WordPress güvenliği ve AB uyumluluğu rehberlerini yazıyor.

Yapay zekâ desteğiyle hazırlanmış ve yayından önce doğruluğu kontrol edilmiştir. Bu makale genel bilgi niteliğindedir, hukuki danışmanlık değildir.