İçeriğe geç
Sedat Özdemir
Yazılar

appsec

Sadece Yamayı Geçmekle Bitmiyor: Zafiyetlerin Görünmeyen Yüzü ve 'Hata' Payımız

Zafiyet dediğimiz şey sadece bir CVE kodundan ibaret değil. Bazen en büyük açık, kodun içinde değil, o kodu kurgularken kurduğumuz mantığın ta kendisinde gizli.

Sedat Özdemir
· 4 dk okuma

Sektördeki ilk senelerimdi, heyecan tavan. Bir finans kuruluşuna sızma testi yapıyoruz. Elime bir tool geçmiş, tarama yapıyor ama nasıl hırslıyım... 'Şurayı da bir kurcalayayım' derken, yanlışlıkla bir döngüye girdim ve test ortamı yerine müşterinin canlı ortamındaki (production) bir API ucuna binlerce sahte 'iptal' isteği gönderdim. O gün yaklaşık 15 dakika boyunca sistem kilitlenmişti. Ofisteki o sessizliği ve kulağımdaki o sıcaklığı hiç unutmam. Meğer 'zafiyet' dediğimiz şey sadece yazılımdaki bir bug değilmiş, benim o dikkatsizliğim ve tool'a duyduğum aşırı güven de bir zafiyetmiş. Neyse ki testCompany yöneticileri anlayışlıydı da kariyerim başlamadan bitmedi.

Bugün sizinle biraz dertleşelim istiyorum. Zafiyet (vulnerability) kelimesi dendiğinde çoğumuzun aklına hemen o meşhur CVE (Common Vulnerabilities and Exposures) listeleri, kritiklik skorları ve 'update' butonları geliyor. Ama işin mutfağında, yani biz Red Team tarafında durum pek öyle değil. Bir sistemin ne kadar 'güvenli' olduğu, sadece en son yamaların geçilip geçilmediğiyle ölçülmüyor. Gelin, bu işin biraz daha derinine, o karanlık ve bazen de komik olan mantık hatalarına inelim.

CVE Takıntısından Kurtulmak

Bir sistem yöneticisine 'Zafiyet yönetimini nasıl yapıyorsun?' diye sorduğumda genellikle 'Scanner çalıştırıyorum, çıkanları yamalıyorum' cevabını alıyorum. Bu harika bir başlangıç ama sadece başlangıç. Otomatize araçlar, kapının kilidinin bozuk olup olmadığını söyler ama anahtarı paspasın altına koyup koymadığınızı her zaman göremez.

Örneğin, en son model bir güvenlik duvarınız (Firewall) olabilir, tüm sunucularınız son sürüm Linux çekirdeği kullanıyor olabilir. Ama eğer yazılımcı arkadaşım, kullanıcı profilini güncellerken user_id parametresini kontrol etmeyi unuttuysa, geçmiş olsun. İşte biz buna mantık hatası (Business Logic Flaw) diyoruz ve emin olun, hiçbir otomatik scanner bunu 'kritik' diye önünüze getirmez.

Teknik Bir Bakış: IDOR Dedikleri Belayı Tanıyalım

En sevdiğim zafiyet türlerinden biridir IDOR (Insecure Direct Object Reference). Neden mi? Çünkü basit, etkili ve tamamen insan hatasına dayalı. Bir web uygulamasında kendi profilinize baktığınızı düşünün. URL genelde şöyledir:

https://testCompany.example.com/api/v1/profile/view?user_id=1337

Buradaki 1337 sizin kullanıcı numaranız. Peki, ben bir saldırgan olarak (veya meraklı bir iş arkadaşınız) buradaki rakamı 1338 yaparsam ne olur? Eğer sistem arkada 'Hop kardeşim, sen 1337'sin, 1338'in verisini neden istiyorsun?' demiyorsa, başkasının tüm verileri ekranımda demektir.

Bunu önlemek için yazılması gereken kod aslında çok basit ama o 'deadline' baskısı altında hep unutuluyor. Bakınız bir pseudo-kod örneği:

# ZARARLI/ZAFİYETLİ KOD (Defanged)
def get_user_data(request):
    user_id = request.GET.get('user_id')
    # Sadece ID'ye göre sorgu atıyor, yetki kontrolü yok!
    user_data = db.query("SELECT * FROM users WHERE id = %s", user_id)
    return user_data

# OLMASI GEREKEN GÜVENLİ KOD (Defanged)
def get_user_data_secure(request):
    target_user_id = request.GET.get('user_id')
    current_session_user = request.user.id
    
    # Yetki kontrolü: İsteyen kişi, istediği veri sahibi mi?
    if str(target_user_id) != str(current_session_user):
        return "Hoppala! Yetkiniz yok dostum.", 403
        
    user_data = db.query("SELECT * FROM users WHERE id = %s", target_user_id)
    return user_data

Dependency Hell: Bağımlılıkların Karanlık Yüzü

Bir diğer mesele ise modern yazılım geliştirme dünyasının vazgeçilmezi olan paketler. Bir 'Hello World' projesi bile bazen arkasında 500 tane kütüphane çekiyor. Biz buna 'Dependency Hell' diyoruz. Siz kodunuzu dünyanın en güvenli şekilde yazsanız bile, kullandığınız o çok popüler 'log-helper' kütüphanesinin içindeki bir açık yüzünden tüm sisteminiz patlayabilir.

Log4j vakasını hatırlıyorsunuzdur, değil mi? Tüm dünya bir hafta boyunca uykusuz kalmıştı. İşte bu yüzden zafiyet yönetimi sadece sizin yazdığınız kodla sınırlı değil, kucağınıza aldığınız o koca ekosistemle de ilgili.

Mass Assignment: 'Beni Admin Yap' Parametresi

Bir başka 'geek' favorim ise Mass Assignment. Diyelim ki bir kayıt formunuz var: İsim, soyisim, e-posta. Arka planda bu verileri bir objeye basıp veritabanına kaydediyorsunuz. Saldırgan araya girip (Proxy kullanarak) isteğin içine şöyle bir şey ekliyor:

{"username": "sedat", "email": "[email protected]", "is_admin": true}

Eğer uygulamanız 'Gelen her şeyi objeye doldur' modundaysa (ki birçok framework varsayılan olarak bunu yapar), tebrikler! Hiç yoktan bir admin hesabım oldu.

Bunu engellemek için 'whitelist' mantığını kullanmanız şart. Yani sadece beklediğiniz alanları kabul etmelisiniz:

// ZAFİYETLİ (Defanged)
app.post('/update-profile', (req, res) => {
    User.update(req.body); // Gelen her şeyi sorgusuz sualsiz yutuyor
});

// GÜVENLİ (Defanged)
app.post('/update-profile', (req, res) => {
    const safeData = {
        firstName: req.body.firstName,
        lastName: req.body.lastName
        // is_admin buraya dahil edilmediği için asla güncellenemez
    };
    User.update(safeData);
});

Red Team Ne Yapar?

Biz Red Team olarak bu zafiyetleri bulduğumuzda sadece 'Aha bulduk!' demiyoruz. Bu zafiyetin işe etkisini (business impact) ölçüyoruz. Mesela bir 'Cross-Site Scripting' (XSS) bulduğumuzda, 'Bak buraya script yazdım, alert çıktı' demek çok amatörce bir hareket. Bunun yerine, o XSS'i kullanarak bir yöneticinin oturumunu nasıl çalabileceğimizi veya iç ağa nasıl sızabileceğimizi gösteriyoruz.

Zafiyet yönetimi bir 'checklist' değil, bir süreçtir. Bugün temiz olan sisteminiz, yarın yeni bir 'Zero-Day' ile savunmasız kalabilir. Bu yüzden 'Sızma testini yaptık bitti' kafasından çıkıp, sürekli bir izleme ve test döngüsüne girmemiz gerekiyor.

Son Söz (Ya Da Kahve Molası Önerisi)

Eğer bir yazılımcıysan, yazdığın her satıra 'Birisi burayı nasıl manipüle edebilir?' gözüyle bakmaya çalış. Eğer bir sistemciysen, 'Yamayı geçtim, güvendeyim' deme; ağındaki trafiği izle, anormal hareketleri yakala.

Unutmayın, en büyük zafiyet her zaman teknolojide değil, insanın 'bana bir şey olmaz' demesindedir. Bir sonraki kahve molanızda, kendi sisteminizdeki 'acaba' dediğiniz yerleri bir düşünün. Belki o paspasın altındaki anahtarı çekip almanın vakti gelmiştir.

Kendinize iyi bakın, güvenli kod yazın!

İlgili yazılar