teknikbakis
Saha derlemesi · beş denetimin sentezi

Beş denetim, 86 bulgu: tekrar eden sekiz hata

Mart–Ağustos 2026 arasında beş ayrı sistemi denetledik: iki müşteri altyapısı, bir eğitim platformu, kendi honeypot ekosistemimiz ve kendi ürünümüzün bir modülü. Toplam 86 bulgu çıktı, 15'i kritik. Bulguları yan yana koyunca şaşırtıcı olan şu: hedefler, ekipler ve teknoloji yığınları birbirinden bağımsızdı ama hatalar aynıydı.

KAYIT TB-2026-004
KAPSAM 5 sistem denetimi
BULGU 86
KRİTİK 15
DÖNEM 2026-03 → 2026-08
TİP Derleme

Bu derleme neye dayanıyor

Aşağıdaki her iddia, yürütülmüş bir denetimin kayıtlı bulgusuna dayanıyor. Müşteri adı, alan adı, IP ve günlük kaydı yayınlanmıyor; sistemler türleriyle anılıyor.

Denetlenen sistemTarihBulguKritik
Danışmanlık platformu (Faz-0, KVKK kapsamlı)2026-0682
Kurumsal CRM + web altyapısı2026-0675
Kendi honeypot ekosistemimiz2026-05203
Eğitim platformu2026-0570
Kendi ürünümüzün bir modülü2026-08445

Listede kendi sistemlerimiz de var — ve en çok bulgu onlardan çıktı. Bu bir tesadüf değil: kendi kodunu denetlerken erişimin tam, bahanen yok.

Yöntem notu Neden bu sekiz başlık?

86 bulguyu tek tek kategorize edip birden fazla denetimde tekrar edenleri ayırdım. Aşağıdaki sekiz desenin her biri en az iki bağımsız sistemde ortaya çıktı. Yalnız bir yerde görülen bulgular — ne kadar ilginç olursa olsun — bu listeye girmedi.


1. Kimlik doğrulama var sayılıyor, ama yok

En yıkıcı ve en sık bulgu bu. Beş denetimin üçünde, kimlik doğrulaması olduğu varsayılan uç noktaların gerçekte tamamen açık olduğunu gördük.

  • Anonim yıkıcı CRUD (CVSS 9.1) — API'nin oluştur/güncelle/sil işlemleri kimlik istemiyordu. Kimliksiz bir istek veriyi silebiliyordu.
  • Anonim kişisel veri okuma (CVSS 8.6) — başvuru kayıtları, ad-soyad ve iletişim bilgileriyle birlikte yetkisiz okunabiliyordu.
  • Parolasız yönetici girişi (CVSS 9.8) — geliştirme kolaylığı için eklenmiş bir /auto-login uç noktası üretimde duruyordu.
  • Kimlik doğrulamasız yönetim API'si0.0.0.0 üzerinde dinliyor, tüm veriyi açıyordu.
  • Anonim dosya yükleme (CVSS 7.3) — yüklenen dosya doğrudan web köküne yazılıyordu.

Bunların hiçbiri karmaşık bir zafiyet değil. Ortak kök, tek bir cümlede özetlenebilecek bir varsayım: "bu adresi zaten sadece bizim arayüzümüz çağırıyor." Arayüz çağırıyor olabilir; ama adres internete açıksa çağıran tek şey o değildir.

NASIL YAKALANIR

Uygulamanızın kullandığı her uç noktayı, oturum çerezi ve Authorization başlığı olmadan çağırın. Tarayıcıdan değil, ayrı bir terminalden. 200 dönen her yanıt bir bulgudur. Bu testin tamamı bir öğleden sonra sürer ve beş denetimin üçünde kritik bulgu çıkardı.

2. Sırlar kodun içinde yaşıyor

İkinci sırada sır yönetimi var. Burada ilginç olan, ekiplerin sır yönetiminin gerektiğini bilmesi ama uygulamanın yarım kalması.

  • Canlı API anahtarı ve veritabanı parolası, sürüm kontrolünde izlenen bir .env dosyasında düz metin.
  • Bulut sağlayıcısının hizmet hesabı özel anahtarı, dışarıdan erişilebilir bir konumdan sızıyordu (CVSS 7.5).
  • Veritabanı tohumlama (seeder) dosyalarında varsayılan yönetici parolaları — üretim veritabanında hâlâ geçerliydi.
  • API anahtarı komut satırı argümanı olarak geçiriliyordu; makinedeki herhangi bir kullanıcı ps ile görebilirdi.

Son madde özellikle sinsi: geliştirici sırrı ortam değişkeninden okuyup "güvenli" davrandığını düşünüyor, sonra onu bir alt sürece argüman olarak veriyor. Sır, süreç tablosuna düşüyor.

NASIL YAKALANIR

Depo geçmişinizi tarayın — mevcut hâlini değil, geçmişini. Bir sır bir kez işlendiyse silinmesi yetmez, geçersiz kılınması gerekir. Ayrıca üretim makinesinde ps auxww çıktısını okuyun; orada gördüğünüz her anahtar sızmıştır.

3. Doğrulama yanlış katmandan yapılıyor

Bu, listedeki en pahalı hata — çünkü ekibe "kontrol ettim" duygusu verir ve aramayı aylarca yanlış yöne gönderir. Üç ayrı örnek:

Örnek A Host'tan test edildi, isteği yapan container'dı

Bir sunucu sertifika alamıyordu. Host üzerinden curl ile dış erişim test edildi — çalışıyordu. Bu sonuç "sorun sunucuda değil" çıkarımına yol açtı ve dosya dört ay kapanmadı. İsteği yapan host değil, container'dı; container'ın çıkışı kapalıydı. Ayrıntısı ayrı kayıtta: TB-2026-001.

Örnek B Testler 30/30 geçiyordu, modül çalışmıyordu

Kendi ürünümüzdeki bir metin denetim modülünün otomatik testleri tamamen yeşildi. Çekişmeli bir denetim açtığımızda modülün en tipik cümlede çalışmadığı ortaya çıktı: aradığı şeyi kaçırıyor, aramadığı şeyi yakalıyordu. Testler modülün gerçek girdisini değil, geliştiricinin hayal ettiği girdiyi içeriyordu. Bu denetim tek başına 44 bulgu üretti.

Örnek C "Gönderildi" sayacı varmayı garanti etmiyor

Bir VPN istemcisi "740 bayt gönderildi, 0 bayt alındı" gösteriyordu. Gönderim sayacı dürüsttü — paket gerçekten yerel soketten çıkmıştı, sadece hiçbir yere varmıyordu. Karşı tarafta dinlemeden bu fark görülmez: TB-2026-002.

KURAL

Testi, işi gerçekten yapan bileşenin içinden çalıştırın ve sonucu karşı uçtan doğrulayın. Host'tan yapılan test container'ın ağ yolunu kanıtlamaz; gönderen tarafın sayacı alıcının varlığını kanıtlamaz; geliştiricinin yazdığı test kullanıcının gireceği veriyi kanıtlamaz.

4. Varsayılan ayarlar üretime çıkıyor

Hiç kimsenin bilinçli olarak vermediği, sadece değiştirilmediği için orada duran kararlar. Denetimlerde tekrar tekrar çıktılar:

BulguNeden varsayılan kaldıÖnem
SSH'ta root girişi + parola doğrulama açıkKurulum sihirbazı böyle bırakır9.0
Sunucuda paket filtresi hiç yok"Sağlayıcı hallediyordur"9.1
API oturum jetonlarında son kullanma yokÇerçevenin varsayılanı süresiz7.5
Yönetici panelinde deneme sınırı / MFA yokSonraya bırakılmış8.1
CORS joker karakterle açıkGeliştirmede çözüm, üretimde kalıntı3.1
Eski TLS sürümleri ve zayıf şifre takımıUyumluluk kaygısıyla açık bırakılmış7.0

Bu tablodaki her satır, kurulumdan sonra bir kez bakılsa kapanacak şeyler. Ama kimse bakmıyor, çünkü sistem çalışıyor. Çalışmak ile güvenli olmak farklı durumlar; varsayılanlar birincisini sağlar, ikincisini değil.

5. Girdi güvenilir sayılıyor — ve girdi artık yalnız kullanıcıdan gelmiyor

Klasik enjeksiyon hataları hâlâ yaşıyor: dizgi birleştirmeyle kurulan SQL koşulları, shell=True ile çalıştırılan biçimlenmiş komutlar, doğrulanmadan yola eklenen adres bileşenleri.

Yeni olan şu: artık girdi bir dil modelinden de gelebiliyor. Kendi honeypot altyapımızda, saldırgan verisini özetleyen bir model çıktısı, müşteri raporuna kaçış yapılmadan yazılıyordu. Yani saldırgan, honeypot'a bıraktığı metinle rapora komut dosyası sokabilirdi — model üzerinden dolaşan bir kalıcı XSS. Aynı yerde ikinci bir bulgu, saldırganın tehdit etiketini model üzerinden manipüle edebilmesiydi.

Yeni yüzey Model çıktısı kullanıcı girdisidir

Bir dil modelinin ürettiği metni "bizim ürettiğimiz içerik" saymayın. Model, girdisini nereden aldıysa onun etkisi altındadır. Rapora, arayüze veya veritabanına giderken tıpkı form verisi gibi kaçışlanmalı ve doğrulanmalıdır.

6. Türkçe kör noktası

Bu başlık uluslararası kaynaklarda neredeyse hiç geçmiyor, ama Türkiye'de yazılan her metin işleyen sistemi vuruyor. Kendi ürünümüzün denetiminde beş kritik bulgunun beşi buradan çıktı.

  • Sözcük sınırı çalışmıyor. Düzenli ifadelerdeki \b Türkçe harfleri sözcük karakteri saymaz. "beş", "üç", "altmış" gibi sözcükleri arayan bir kural sessizce hiçbir şey bulmaz — hata da vermez.
  • Küçük harfe çevirme iki yönde de bozuk. Programlama dillerinin varsayılan dönüşümü ASCII I harfini ı yapar; böylece "Instagram" araması eşleşmez. Ters yönde, lang="tr" altında büyük harfe çevirme İngilizce i'yi İ yapar ve arayüzde "FortiGate" yazısı "FORTİGATE" olur.
  • Alt dize eşleştirme masumu vurur, hedefi gizler. Bir sözcüğün içinde geçen kısa dizi yüzünden eşleşen kural, gerçek hedefi görünmez kılar. Denetimde "gravür", "ekonomi", "not" gibi sözcüklerin yanındaki gerçek telefon numarası hiçbir iz bırakmadan yutuluyordu.

Üçünün ortak özelliği sessiz olmaları. Sistem hata vermez, log düşmez, test kırmızıya dönmez. Sadece yanlış cevap verir. Türkçe içerik işleyen bir kural yazdıysanız, onu Türkçe karakter içeren gerçek cümlelerle sınayın — İngilizce örneklerle geçen test hiçbir şey kanıtlamaz.

7. Belge ile sistem birbirinden ayrışıyor

Denetimlerde tekrar eden bir bulgu tipi de dokümantasyonun yalan söylemesiydi: teknik şartname bir modülün "bu sürümde bulunmadığını" yazarken modül canlıda ve aynı sayfanın menüsünden bağlıydı; proje notu bir işin "kapandığını" söylerken ilgili bağlantı hiç kurulmamıştı; kod yorumu artık geçerli olmayan bir davranışı anlatıyordu.

Bu bir "belgeler eskimiş" sorunu gibi görünür, ama sonucu güvenlik sonucudur: bir sonraki değişikliği yapan kişi belgeye güvenerek karar verir. Yanlış varsayımla yazılmış doğru kod, yanlış kod üretir. Denetimlerde gördüğümüz birkaç kritik bulgunun kökeninde, birinin eski bir belgeye güvenmiş olması vardı.

8. Sessiz başarısızlık — listedeki en pahalı desen

Sondaki bu desen aslında diğer yedisinin taşıyıcısı. Bir sistem bozuk çalıştığını söylemiyorsa, bozukluk sıraya hiç girmez.

  • Sertifika alınamıyordu ve deneme sayısı 136'ya çıkmıştı; kimse fark etmemişti, çünkü önde bir içerik dağıtım ağı vardı ve ziyaretçi bir hata görmüyordu.
  • Fazla kapatan bir güvenlik duvarı kuralı hata üretmez. Sadece bazı şeyler "bazen olmaz" — ve bu, teşhis edilmesi en zor arıza tipidir.
  • Kendi ürünümüzde, kullanıcıyı uyarması gereken bir bileşen uyarısını ekranın görünmeyen kısmında gösteriyordu. Modül teknik olarak çalışıyor, işlevsel olarak hiç çalışmıyordu.
  • Aynı modülde ekran okuyucuya yapılan duyuru her tuş vuruşunda tetikleniyor, 70 vuruşta aynı cümleyi 70 kez kuyruğa atıyordu. Erişilebilirlik özelliği vardı; kullanılabilir değildi.
Asıl soru Bozulduğunu nereden anlayacaksınız?

Bir güvenlik kontrolü kurarken sorulacak soru "çalışıyor mu?" değil, "çalışmayı bıraktığında bunu kim, ne kadar sürede öğrenir?" olmalı. Denetimlerde gördüğümüz kritik bulguların çoğu, çalışmayı bıraktığını kimseye söylemeyen kontrollerdi.


Sekiz desenin tek ortak kökü

Bu sekiz başlık farklı katmanlarda görünüyor — ağ, uygulama, süreç, dil, belge. Ama hepsinin altında aynı şey var: doğrulanmamış varsayım.

"Bu uç noktayı sadece bizim arayüzümüz çağırır." "Sağlayıcı güvenlik duvarını hallediyordur." "Testler geçiyorsa modül çalışıyordur." "Host'tan çıkabiliyorsa container da çıkabilir." "Belge böyle diyorsa öyledir." Her biri makul; hiçbiri sınanmamış.

Denetimin işi zeki saldırı teknikleri bulmak değil — o beklentiyi karşılayan bulgu 86'nın içinde birkaç tane. Denetimin işi, herkesin doğru varsaydığı cümleleri tek tek sınamak. Bulguların büyük çoğunluğu, birinin bir kez bakmasıyla kapanacak şeylerdi.

Kendi listenizi çıkarmak isterseniz basit bir yerden başlayın: sisteminiz hakkında söylediğiniz cümleleri yazın, sonra her birinin yanına bunu en son ne zaman ve nasıl doğruladım diye not düşün. Boş kalan satırlar, bir sonraki denetimin bulgu listesidir.