Güvenlik

WordPress REST API Güvenliği; Kullanıcı Sızıntısını Kapatmak

WordPress endpoint'iniz kullanıcı listesini sızdırıyorsa veya botlar üzerinden giriş yapıyorsa, bu kılavuz gerçekten tehlikeli olan noktaları tam olarak kapatıyor.

Güvenlik

Tek bir basit istek yeterli: curl -s https://example.com/wp-json/wp/v2/users. Eğer JSON çıktısı slug ve name ile doluysa, sitenizin tüm yazarlarının ve yöneticilerinin kullanıcı adları şu anda herkese açık. Saldırganın tahmin etmesine gerek yok; listeyi alır ve sonra sadece gerçek isimler üzerinde şifreyi dener. Bu, WordPress'teki çoğu credential stuffing saldırısının başlangıç noktasıdır.

Çoğu kişinin ilk tepkisi tüm REST API'yi kapatmaktır. Bu işe yarar, ancak bedelini sonra ödersiniz: Gutenberg blok düzenleyicisi yazıyı kaydetmek için aynı API'yi kullanır, form ve mağaza eklentileri de aynı şekilde. Site görünüşte sağlıklı açılır ve sonra taslak kaydetme veya sipariş kaydında belirsiz bir hata verir. Yani amaç, hassas endpoint'leri kapatmaktır, tüm hizmeti öldürmek değil.

WordPress REST API neden kullanıcı listesini sızdırıyor

Bu davranış bir hata değil; varsayılan tasarımdır. /wp-json/wp/v2/users yolu, istemci tabanlı arayüzler oluşturmak için tasarlanmıştır ve varsayılan olarak yalnızca en az bir yayınlanmış yazısı olan kullanıcıları döndürür. Sorun şu ki, birçok sitede yönetici aynı zamanda yazardır, dolayısıyla yöneticinin kullanıcı adı da aynı listede görünür.

Temiz çözüm, bu endpoint'i misafir kullanıcılar için filtrelemektir. Bu kodu alt tema functions.php dosyasına veya bir mu-plugin'e koyun:

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

Bu değişiklikten sonra, ilk curl komutu {"code":"rest_no_route","message":"No route was found..."} döndürmelidir. Hâlâ listeyi görüyorsanız, sayfa önbelleği veya object önbelleği hâlâ eski sürümü sunuyor demektir; önbelleği temizleyin ve tekrar test edin.

Burada hata yapıyorlar

Yaygın hata, yalnızca /wp/v2/users yolunu kapatıp ?author=1 yolunu unutmaktır. WordPress, https://example.com/?author=1 ile sizi yazar arşivine yönlendirir ve nihai URL'de author_name sızar. İşareti de şudur: REST API testiniz geçer ama harici tarama araçları hâlâ kullanıcı adını bulur. Bu yolu kapatmak için yazar arşivi yönlendirmesini devre dışı bırakın veya bir rewrite kuralıyla ana sayfaya yönlendirin.

Hassas endpoint'leri sınırlama ve rate limit

Kullanıcı listesini kapatmak yeterli değil. İki endpoint daha kontrol edilmelidir: bazı ayarlarda taslak içeriği sızdırabilen /wp/v2/posts ve WordPress çekirdeğinde bulunmayan ancak JWT ve uygulama eklentilerinin eklediği kimlik doğrulama yolu.

İstek hızını sınırlamak için iki yolunuz var. Sunucuya erişiminiz varsa, Nginx'te bunu server bloğunun içine koyun:

limit_req_zone $binary_remote_addr zone=wpapi:10m rate=20r/m;

location /wp-json/ {
    limit_req zone=wpapi burst=5 nodelay;
    limit_req_status 429;
    try_files $uri $uri/ /index.php?$args;
}

20r/m sayısı, her IP'den dakikada yirmi istek anlamına gelir. Normal siteler için bu sayı cömerttir; ancak sitenizin mobil uygulaması varsa veya blok düzenleyici sayfasını çok kullanıyorsa, bu sayı gerçek kullanıcılar için 429 hatasına neden olur. Bu durumda burst'ü artırın veya /wp-json/wp/v2/ yolunu sınırlamadan muaf tutun ve yalnızca kimlik doğrulama yollarında katı olun.

Sunucu yapılandırmasına erişiminiz yoksa, güvenlik eklentileri aynı işi PHP katmanında yapar, ancak dikkat edin: her istek hâlâ PHP'ye ulaşır ve işlem yükünü ödersiniz. Yüksek trafikli siteler için ağ kenarında sınırlama, PHP'de sınırlamadan daha iyidir. Siteniz hacim saldırılarının da hefisiyse, bu ayarları DDoS koruması ile birleştirmek, tek bir katmana güvenmekten daha mantıklıdır.

WordPress REST API'de kimlik doğrulama

WordPress varsayılan olarak REST kimlik doğrulaması için çerez ve nonce kullanır. Bu tarayıcı için iyidir, ancak harici uygulamalar için çalışmaz ve bu yüzden geliştiriciler Application Password veya JWT'ye yönelir.

Application Password'ü Kullanıcı → Profil yolundan etkinleştirin. Her şifre belirli bir cihaza bağlanır ve her an iptal edilebilir. Bunu JWT'ye tercih ederim, çünkü JWT'nin WordPress uygulamalarında genellikle ortak bir gizli anahtarı vardır ve bu sızarsa, süresi dolana kadar verilen token'ı iptal etmenin hiçbir yolu yoktur. Application Password'ü o anda silebilirsiniz.

Daha az uyulan nokta: her Application Password yalnızca bir hizmet için olmalıdır. Bir şifreyi yedekleme betiği ile mağaza eklentisi arasında paylaşırsanız, sızıntı anında hangi yolun sızdığını anlayamazsınız ve hepsini iptal etmek zorunda kalırsınız. Bu şifreleri ekipte yönetmek için, Ekiplerde şifre yönetimi yazısında anlatılan ilkeler burada da tam olarak geçerlidir.

Gerçekten kötüye kullanımı engelleyen güvenlik başlıkları

REST yanıtlarında üç başlık en büyük etkiye sahiptir:

  • X-Content-Type-Options: nosniff — tarayıcının JSON yanıtını HTML olarak yorumlamaması için.
  • Sınırlı Content-Security-Policy — bir yerde XSS çalışırsa, kullanıcının çereziyle REST isteği gönderememesi için.
  • * yerine belirli Access-Control-Allow-Origin — diğer sitelerin kullanıcınızın tarayıcısından istek gönderememesi için.

Açık CORS başlığı tek başına bir güvenlik açığı değildir, ancak kimlik doğrulama çereziyle birleştiğinde tam bir CSRF'ye dönüşür. Bir eklenti bu başlığı açtıysa, öncelikle onu ele alın.

REST isteklerini izleme ve günlükleme

Günlük olmadan, birinin endpoint'lerinizi taradığını anlayamazsınız. Yapabileceğiniz en az şey, 401 ve 429 isteklerini IP ve yol ile günlüğe kaydetmektir. Nginx'te:

log_format apilog '$remote_addr $status $request_uri $http_user_agent';
access_log /var/log/nginx/wpapi.log apilog;

Sonra bir grep " 429 " /var/log/nginx/wpapi.log | awk '{print $1}' | sort | uniq -c | sort -rn | head ile en hızlı saldırganları görürsünüz. Bir IP birkaç dakika içinde yüzlerce kez 429 aldıysa, onu güvenlik duvarında kapatma zamanıdır. Bu günlükleri ana erişim günlüğünden ayrı tutun ve rotasyonları olduğundan emin olun, yoksa sunucu diskini doldururlar. Bu günlükleri saklama ve bozulmadan koruma ilkeleri, Denetim günlüğü nedir yazısında açıklananla aynıdır.

Hangi seçeneği seçmeliyim?

YaklaşımAvantajMaliyetNerede seçerim
REST API'yi tamamen devre dışı bırakmaKüçük saldırı yüzeyiGutenberg ve eklentileri bozarStatik ve blok düzenleyicisiz siteler
Endpoint'leri filtrelemeSiteyi bozmadan güvenlikKod bakımı gerektirirÇoğu site için varsayılan tercihim
Nginx'te hız sınırlamaPHP'ye yük bindirmezSunucu erişimi gerektirirYüksek trafikli ve saldırı hedefi siteler

Yalnızca bir şey yapabiliyorsanız, /wp/v2/users filtresini ve ?author= kapatmasını yapın. Bu ikisi, siteyi bozma riski en düşükken en yüksek getiriyi sağlar. Hız sınırlamayı, normal site trafiğini engellemediğinden emin olduktan sonra ekleyin.

Herhangi bir değişiklikten önce veritabanı ve dosyaların yedeğini alın ve uyguladıktan sonra curl ve gerçek bir tarayıcıyla test edin. Siteniz ServerNet altyapısında barındırılıyorsa ve bu katmanları ağ tarafından da güçlendirmek istiyorsanız, güvenlik hizmetleri mantıklı bir başlangıç noktasıdır. DNS kayıtlarını ve ağ yollarını hızlıca kontrol etmek için de DNS ve ağ kontrol araçları işi kolaylaştırır.

Sık sorulan sorular

WordPress REST API'yi tamamen devre dışı bırakmak daha mı güvenli?

Mutlaka değil. Tam devre dışı bırakma saldırı yüzeyini azaltır, ancak blok düzenleyici, form eklentileri ve birçok mağaza eklentisi aynı API'yi kullanır ve çalışmaz hale gelir. Çoğu durumda, kullanıcı listesi gibi hassas endpoint'leri filtrelemek daha iyi sonuç verir.

Sitemin WordPress REST API'sinin kullanıcı listesini sızdırdığını nasıl anlarım?

https://example.com/wp-json/wp/v2/users adresine basit bir istek gönderin. Yanıt JSON'u kullanıcı adlarını ve slug'ları içeriyorsa, listeniz herkese açıktır. ?author=1 yolunu da ayrıca test edin, çünkü biri kapalı diğeri açık olabilir.

REST API'de istek hızı sınırlaması kaç olmalı?

Normal siteler için her IP'den dakikada yirmi istek iyi bir başlangıç noktasıdır. Mobil uygulamanız veya blok düzenleyiciyi çok kullanan kullanıcılarınız varsa, bu sayı gerçek kullanıcılar için 429 hatasına neden olur ve burst'ü artırmanız veya okuma yollarını muaf tutmanız gerekir.

Application Password mı yoksa JWT mi daha güvenli?

Çoğu site için Application Password'ü tercih ederim, çünkü her şifre bir cihaza bağlanır ve her an iptal edilebilir. JWT'nin WordPress uygulamalarında genellikle ortak bir anahtarı vardır ve verilen token'ı iptal etmek kolay değildir.

ServerNet Destek

ServerNet mühendislik ve yayın ekibi — altyapı, ağ ve web barındırma uzmanları.

Güvenlik Hizmetleri
Paylaş:

Yorumlar 0

Henüz yorum yok — ilk siz olun!

Yorum bırakın

İlgili hizmet

Güvenlik Hizmetleri

OSCP sertifikalı uzmanlarla sızma testi, altyapı sıkılaştırma ve 7/24 güvenlik izleme.