Özet. WordPress için Maintenance eklentisi, bakım duvarını kaldırıp kaldırmayacağına ziyaretçinin denetlediği bir çereze bakarak karar veriyor ve o çerezi yapılandırılmış gizli anahtarla hiç karşılaştırmıyor. Boş olmayan herhangi bir değer yeterli. Bu yazıda açığın sınıfını (bozuk erişim denetimi, CWE-284/CWE-639), denetimin yanlışa saptığı tam satırı, kimliği doğrulanmamış bir isteğin oraya nasıl ulaştığının kavramsal anlatımını ve bunun getirdiği düzeltme ile tespit adımlarını bulacaksınız. Eklenti bu satırların yazıldığı anda yamasız; bu yüzden çalışan kavram kanıtı, bir düzeltme çıkana dek metnin dışında tutuluyor. Amaç bir saldırı sunmak değil, örüntüyü anlatmak.
Anahtar kelimeler: WordPress güvenliği, bozuk erişim denetimi, yetki denetimi atlatma, çerez doğrulama, CWE-284, CWE-639, güvenli kodlama.
1. Giriş
Neredeyse her WordPress sitesi bir noktada bakım ya da "yakında" aşamasından geçer — kurulum, taşıma ya da bilinçli bir çevrimdışı alma sırasında — ve sahibi hazır olana dek gerçek ön yüzü bir bekleme sayfasının arkasına saklayan bir eklenti devreye girer. WebFactory Ltd'nin geliştirdiği Maintenance eklentisi tam olarak bunu bir milyonun üzerinde sitede yapıyor. Bu kadar yaygın bir eklenti tüm güvenlik iddiasını tek bir garantiye dayandırıyorsa, o garantideki her çatlağa yakından bakmak gerekir.
Garantinin kendisi dar: ayrıcalığı olmayan ziyaretçi bakım sayfasını görür, başka bir şey görmez. Bu garanti, "bu ziyaretçiyi içeri al" kararı ziyaretçinin dilediği gibi ayarlayabildiği bir değere bağlandığı anda çöker. İstemciden gelen bir belirtece, sunucu doğrulamış gibi güvenmek ders kitaplık bir bozuk erişim denetimidir — hem yaygındır hem de üzerinden anlatmaya elverişlidir — ki yama beklenirken belgelemeye değmesinin nedeni de budur.
2. Etkilenen bileşen
| Alan | Değer |
|---|---|
| Eklenti | Maintenance |
| Slug | maintenance |
| Üretici | WebFactory Ltd |
| Eklenti URL | https://wordpress.org/plugins/maintenance/ |
| Test edilen / Etkilenen sürüm | 4.32 (test sırasındaki en güncel sürüm, 2026-10-05); zafiyetli mantık uzun süredir mevcuttur ve aynı skip_maintenance_mode çerez denetimini taşıyan önceki sürümlerde de büyük olasılıkla vardır |
| Etkin kurulum | 1.000.000+ |
| Zafiyet türü | Bozuk Erişim Denetimi — Bakım Modu Atlatma |
| CWE | CWE-284 (Uygunsuz Erişim Denetimi) / CWE-639 (Kullanıcı Kontrollü Anahtar ile Yetkilendirme Atlatma) |
| Gereken kimlik doğrulama | Yok (kimlik doğrulamasız) |
| CVSS 3.1 (önerilen) | 5.3 Orta — AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N |
| Durum | Yama yok (yayın anında 0-day) |
3. Teknik analiz
Bakım modu, çok geç bir öncelikle bağlanan bir template_include kancasıyla uygulanıyor; bu kanca yönetici olmayan her ziyaretçi için bakım şablonunu araya sokuyor:
// line ~104
add_action('template_include', array($this, 'template_include'), 999999);Eklentide bir de "Direct Access Link" (Doğrudan Erişim Bağlantısı) özelliği var. Sahibi gizli bir belirteç (direct_access_link) ayarlıyor; bu gizli anahtarı sorgu dizesi parametresi olarak sunan ziyaretçi içeri alınıyor ve eklenti, muafiyet 24 saat sürsün diye bir skip_maintenance_mode çerezi bırakıyor. Buraya kadar sorun yok. Sorun, muafiyetin sonraki isteklerde nasıl denetlendiğinde.
// load_maintenance_page() içinde (~satır 4331'de başlar)
// satır ~4346 — çerez YALNIZCA gizli direct_access_link sunulduğunda AYARLANIR
$custom_url_link = $mtnc_options['direct_access_link'];
if (!empty($custom_url_link)) {
if (isset($_GET[$custom_url_link])) {
setcookie("skip_maintenance_mode", true, time() + 24 * 60 * 60, '/');
$_COOKIE['skip_maintenance_mode'] = true;
}
}
// ... daha sonra, atlatma KONTROLÜ (satır ~4421) ham istemci çerezine güvenir:
if (!empty($_COOKIE['skip_maintenance_mode'])) {
$show_maintenance_page = 0; // HATA: HERHANGİ BİR çerez değerinin varlığı duvarı kaldırır
}Yazma yolu olması gerektiği gibi davranıyor: çerez ancak doğru gizli anahtar ortaya çıktıktan sonra bırakılıyor. Dağılan yer okuma yolu, çünkü yetki kararı baştan sona !empty($_COOKIE['skip_maintenance_mode']) üzerinde duruyor. Bu değer hiçbir zaman direct_access_link ile karşılaştırılmıyor, imzalanmıyor, sunucu tarafı bir oturuma ya da saklı bir duruma bağlanmıyor. Çerez baştan sona istemci verisidir; bir çerezin salt varlığını yetki kanıtı sayan eklenti de kararı istemciye bırakmış olur — artık istemcinin yetkili olup olmadığına istemci karar verir.
Bu, CWE-284'ün (uygunsuz erişim denetimi) üstüne oturan CWE-639'dur (kullanıcı kontrollü anahtar ile yetkilendirme atlatma). Gizli belirteç tasarımı sağlamdır; yıkılmasının nedeni, doğrulama adımının yanlış özelliğe — değerin var olup olmadığına — bakması, gizli anahtarla kriptografik eşitliğe bakmamasıdır.
4. Açığa nasıl ulaşılıyor (kavramsal)
Bozuk denetime ulaşmak için ne ayrıcalık, ne hesap, ne de gizli anahtar bilgisi gerekir. Bakım filtresi, anonim ziyaretçilerin sıradan ön yüz isteklerinde çalışır — zaten bütün amacı budur — ve her istekte eklenti, bekleme sayfasıyla gerçek site arasında seçim yapmak için skip_maintenance_mode çerezini okur.
HTTP istemcisi gönderdiği çerezlerin sahibi olduğundan ve denetim herhangi boş olmayan değeri geçirdiğinden, eklentinin yanıtladığını sandığı soru ("bu ziyaretçi daha önce doğru gizli anahtarı sundu mu?") sessizce ziyaretçinin kendi yanıtladığı bir soruya ("içeri girmek istiyor muyum?") dönüşür. Zafiyetin tamamı, korunan yazma ile korunmayan okuma arasındaki bu boşluktur: gizli anahtar yalnızca çerezin otomatik ayarlanmasının kolaylığını korur, çerezin onurlandırılmasını değil. Gizli anahtarı hiç görmemiş bir ziyaretçi, onu yalnızca iddia ederek aynı "içeri alınmış" duruma düşer.
Bunu gösteren isteği bilerek dışarıda bırakıyoruz. Yukarıdaki mekanizma, riski ölçmek ve bir düzeltmeyi doğrulamak için gereken her şeyi veriyor; kopyala-yapıştır bir saldırı dizesi bunun üstüne hiçbir şey katmaz ve yamalı bir sürüm çıkana dek saklı kalır.
5. Etki değerlendirmesi
Kimliği doğrulanmamış bir saldırgan bakım duvarını aşıp yöneticinin gizli tutmak istediği canlı ön yüz içeriğini görür — lansman öncesi bir site, yapım aşamasındaki bir çalışma ya da bilerek çevrimdışı alınmış bir site. Eklentinin var olma nedeni tam da bunu engellemektir.
Etki alanı dardır. Atlatma yalnızca duvar kalktığında WordPress'in ön yüz ziyaretçilerine zaten sunacağı içeriği açar; tek başına wp-admin'e, eklenti ayarlarına ya da veritabanına erişim vermez ve hiçbir şeyi değiştirmez. Önerilen CVSS'i 5.3 Orta (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N) düzeyine yerleştiren de bu yalnızca-okuma, yalnızca-gizlilik niteliğidir: ağ üzerinden erişilebilir, düşük karmaşıklık, ayrıcalık ya da etkileşim gerekmez, kapsam değişmez, sınırlı gizlilik etkisi, bütünlük veya erişilebilirlik etkisi yok. Yine de gizlenen içerik hassassa iş maliyeti gerçek olabilir — yayımlanmamış ürünler, hazırlık (staging) verileri ya da tam da kimse görmesin diye indirilmiş bir site.
6. Düzeltme
Çerezin var olmasına güvenmek yerine değerini doğrulayın. Atlatmayı yalnızca çerez değeri yapılandırılmış gizli anahtarla eşleştiğinde, sabit zamanlı karşılaştırmayla onurlandırın:
if (
!empty($mtnc_options['direct_access_link'])
&& !empty($_COOKIE['skip_maintenance_mode'])
&& hash_equals((string) $mtnc_options['direct_access_link'], (string) $_COOKIE['skip_maintenance_mode'])
) {
$show_maintenance_page = 0;
}Doğru direct_access_link sorgu parametresi geldiğinde ise çerez değerini true yerine gizli anahtarın kendisine — daha iyisi, sunucuda üretilmiş imzalı bir belirtece — ayarlayın. hash_equals(), karşılaştırmayı zamanlama yan kanallarından uzak tutar.
Site sahipleri, üretici bir düzeltme çıkardığı an güncel sürüme geçmelidir. O ana dek aşağıdaki sertleştirme adımları geçerlidir.
7. Site sahipleri için tespit ve sertleştirme
Buradaki her madde doğrudan yukarıdaki mekanizmadan çıkar:
- Bakım modunu erişim denetimi değil, gizleme (obscurity) olarak görün. Gerçekten gizli kalması gereken içerik, ziyaretçinin dokunamayacağı bir katmanın arkasına aittir — HTTP Basic Auth, IP izin listesi, güvenlik duvarı kuralı ya da herkese açık olmayan bir sunucu — tek başına bir ön yüz eklentisine değil.
- Belirtgen istek biçimine dikkat edin.
skip_maintenance_modeçerezi taşıyan ama öncesinde gizlidirect_access_linkparametresini sunan bir isteği olmayan ön yüz istekleri şüphelidir. Web sunucusu ve WAF günlükleri, atlatma çerezini daha gelirken taşıyan istekleri ortaya çıkarabilir. - En az ayrıcalık: özelliği kapatın. "Direct Access Link" özelliğini kullanmıyorsanız yapılandırmadan bırakın ve hassas bir şeyi korumak için ona asla bel bağlamayın.
- Sanal yama (virtual patching). Geçici çözüm olarak bir WAF veya kenar kuralı, resmi düzeltme kurulana dek doğrulanmış bir gizli anahtar olmadan gelen
skip_maintenance_modeçerezini soyabilir ya da yok sayabilir. Bu hafifletir; iyileştirmez. - Eklentiyi güncel tutun ve düzeltilmiş sürümü gecikmeden uygulayabilmek için üreticinin sürüm notlarına abone olun.
8. Daha geniş ders
Varlık, kanıt değildir. Belirtece dayalı bir muafiyet, ancak onu onurlandıran karşılaştırma kadar güçlüdür. Bir sunucu istemciden gelen veriyle yetki kararı verdiğinde — çerez, başlık, sorgu parametresi ya da gizli form alanı — değeri sunucuda tutulan bir gizli anahtara veya sunucu tarafı duruma karşı doğrulamalı, gizli anahtarlar için sabit zamanlı karşılaştırma kullanmalı ve yetkiyi asla alanın salt var olmasından çıkarmamalıdır. Yazmayı koruyup okumayı açık bırakmak sürekli yinelenen bir tuzaktır. Güvenlik özelliği, değerin ilk kez nasıl ayarlandığında değil, denetimde yaşar.
9. Sorumlu ifşa
Bu sorun koordineli ifşa kapsamında ele alındı. Üretici özel olarak ve iyi niyetle bilgilendirildi; çalışan kavram kanıtının tamamı bir düzeltme çıkana dek bu herkese açık yazının dışında tutuluyor. Tam teknik ayrıntıyı yalnızca yamalı bir sürümden sonra ya da üzerinde anlaşılan ifşa penceresinin ardından, zamanlamayı üreticiyle birlikte belirleyerek yayımlayacağız. Tüm doğrulamalar, araştırmacının denetimindeki yerel, izole bir WordPress örneğinde yapıldı; hiçbir üçüncü taraf ya da üretim sistemi test edilmedi, hiçbirine dokunulmadı.
Kaynaklar
- CWE-284: Improper Access Control — https://cwe.mitre.org/data/definitions/284.html
- CWE-639: Authorization Bypass Through User-Controlled Key — https://cwe.mitre.org/data/definitions/639.html
- OWASP: Broken Access Control — https://owasp.org/Top10/A01_2021-Broken_Access_Control/
- WordPress Plugin Developer Handbook — Nonces — https://developer.wordpress.org/apis/security/nonces/
- WordPress Plugin Developer Handbook — Checking User Capabilities — https://developer.wordpress.org/apis/security/user-roles-and-capabilities/
- FIRST CVSS v3.1 Calculator — https://www.first.org/cvss/calculator/3.1
Savunma ve eğitim amacıyla yayımlanmıştır. Noroxi LLC yalnızca yetkili güvenlik araştırması yürütür; operasyonel istismar ayrıntıları bir düzeltme yayımlanana dek saklanır.
Bu hafta sömürülenler · her pazartesi
KEV'e girenler, yeni PoC'ler, WordPress triyajı ve bu hafta ne yapmalı. Hesap gerekmez.