Uygulama geliştirirken güvenlik testleri, kodun kalitesi kadar projenin de geleceğini belirler. Genellikle iki ana yöntem üzerinde durulur: Static Application Security Testing (SAST) ve Dynamic Application Security Testing (DAST). Her ikisi de farklı noktalarda devreye girer ve farklı türde zafiyetleri tespit eder.
Benim 20 yıla yakın tecrübemde, bu iki yöntemi doğru anlamak ve doğru zamanda kullanmak, hem geliştirme hızını artırıyor hem de üretim ortamındaki olası güvenlik açıklarını minimize ediyor. Hatta bazen birinin bulamadığını diğeri bulur, bu yüzden birbirlerini tamamlarlar.
SAST Nedir ve Ne Zaman Kullanılır?
SAST, kodunuzu çalıştırmadan analiz eden bir “beyaz kutu” (white-box) test yöntemidir. Geliştirme sürecinin erken aşamalarında, yani kod daha derlenmeden veya uygulamaya dönüşmeden önce devreye girer. Genellikle CI/CD pipeline’ımın bir parçası olarak otomatik çalıştırırım.
SAST araçları, kaynak kodunuzdaki, bytecode’unuzdaki veya ikili dosyalarınızdaki bilinen güvenlik zafiyeti kalıplarını tarar. Örneğin, bir üretim ERP’si projesinde çalıştığım zamanlarda, SAST araçları sayesinde SQL injection’a açık olabilecek sorguları ya da XSS (Cross-Site Scripting) zafiyetine yol açabilecek input sanitization eksikliklerini erkenden yakaladım. Bu, sonradan oluşabilecek büyük güvenlik sorunlarının önüne geçti.
SAST araçları, özellikle OWASP Top 10 listesindeki birçok zafiyeti (Injection, Broken Authentication, Sensitive Data Exposure gibi) kod seviyesinde tespit etmede çok etkilidir. Örneğin, bir Java uygulamasında Statement yerine PreparedStatement kullanılmaması veya bir Python uygulamasında eval() gibi tehlikeli fonksiyonların kullanılması gibi durumları rahatlıkla yakalar. FastAPI gibi framework’lerde de yanlış kullanılan request.json() parse işlemlerinden kaynaklanabilecek hataları kod seviyesinde işaretleyebilir.
# SAST taramasında potansiyel zafiyet olarak işaretlenecek bir örnek
# Bu kodda, user_input doğrudan SQL sorgusuna eklenirse SQL Injection riski oluşur.
def get_user_data(user_id):
query = f"SELECT * FROM users WHERE id = {user_id}" # SAST burada uyarı verecektir
# ... veritabanı işlemi
DAST Nedir ve Ne Zaman Kullanılır?
DAST, çalışan bir uygulamayı dışarıdan, bir saldırganın gözünden test eden bir “kara kutu” (black-box) test yöntemidir. Uygulama, test sırasında canlı ortamda veya buna çok yakın bir staging ortamında çalışıyor olmalıdır. DAST araçları, uygulamaya HTTP istekleri gönderir, formları doldurur, bağlantılara tıklar ve yanıtları analiz eder.
DAST, özellikle uygulamanın runtime davranışından kaynaklanan zafiyetleri bulmada çok etkilidir. Örneğin, sunucu yapılandırma hataları, kimlik doğrulama akışındaki mantık hataları, yetkilendirme sorunları veya oturum yönetimi zafiyetleri gibi durumlar DAST ile daha iyi tespit edilir. Bir bankanın iç platformu için yaptığımız çalışmalarda, DAST taramaları sayesinde farklı kullanıcı rollerinin yetkisiz verilere erişebildiğini veya hatalı bir API endpoint’inin anonim erişime açık olduğunu tespit ettik.
DAST taramaları genellikle geliştirme döngüsünün sonlarına doğru, QA veya UAT (User Acceptance Testing) aşamalarında devreye girer. Hatta üretim öncesi son güvenlik kontrolü olarak da kullanılır. Bir API’de eksik rate limiting yapılandırması gibi sorunlar da çoğu zaman ancak DAST taramasında ortaya çıkar; bu tür bir eksiklik, brute-force saldırılarına karşı uygulamayı savunmasız bırakabilir.
# DAST taramasından örnek bir çıktı (basitleştirilmiş)
# Bir DAST aracı, aşağıdaki gibi bir istek gönderip yanıtı analiz edebilir:
# Request: GET /api/v1/admin/users/123 HTTP/1.1
# Header: Authorization: Bearer <düşük yetkili token>
# Expected Response: 403 Forbidden
# Actual Response: 200 OK (admin verileri dönüyor)
# Zafiyet: Broken Access Control (Yetkilendirme Hatası)
SAST ve DAST Arasındaki Temel Farklar
SAST ve DAST, uygulama güvenliğine farklı açılardan yaklaşan, ancak birbirini tamamlayan iki yöntemdir. Benim için bu farkları anlamak, hangi aracı ne zaman kullanacağıma karar vermemde kritik oldu. İşte temel farkları özetleyen bir tablo:
| Özellik | SAST (Static Application Security Testing) | DAST (Dynamic Application Security Testing) |
|---|---|---|
| Yöntem | Beyaz kutu (White-box) | Kara kutu (Black-box) |
| Analiz Aşaması | Geliştirme, derleme, commit öncesi | Çalışma zamanı, QA, UAT, üretim öncesi |
| Gereksinim | Kaynak kodu, bytecode veya ikili dosya | Çalışan uygulama (URL, API endpoint) |
| Tespit Ettiği | Kod seviyesindeki zafiyetler (SQLi, XSS, insecure deserialization) | Runtime zafiyetleri (yanlış yapılandırma, yetkilendirme, iş mantığı hataları, session yönetimi) |
| Hassasiyet | Yüksek (kodun her yerine erişebilir) | Orta (uygulamanın dışarıdan görünen kısmını test eder) |
| Yanlış Pozitif | Daha yüksek olabilir | Daha düşük olabilir |
| Hız | Genellikle daha hızlı (birkaç saniye/dakika) | Daha yavaş (dakikalar/saatler sürebilir) |
| Otomasyon | CI/CD pipeline’ına kolay entegre edilir | CI/CD’ye entegre edilebilir ama daha karmaşık olabilir |
Benim pratiğimde, SAST’ın daha çok geliştiricinin kodu yazarken yaptığı hataları bulduğunu, DAST’ın ise uygulamanın genel mimarisindeki veya yapılandırmasındaki zafiyetleri ortaya çıkardığını gördüm. Genel olarak SAST kod kalitesini sürekli yukarı çekerken, DAST entegrasyon noktalarındaki veya sunucu ayarlarındaki gizli sorunları gün yüzüne çıkarır.
İkisini Birlikte Kullanmak: DevSecOps Yaklaşımı
SAST ve DAST’ın birbirini tamamladığını gördükten sonra, benim için asıl soru “Hangisi önce gelmeli?” değil, “Nasıl entegre etmeliyim?” oldu. Cevap, modern DevSecOps yaklaşımında yatıyor: Her ikisini de geliştirme yaşam döngüsünün farklı aşamalarına entegre etmek.
Benim için ideal senaryo şöyle işler:
- Geliştirme ve Commit Öncesi: Geliştiriciler yerel ortamda veya commit öncesinde lightweight SAST araçlarını çalıştırır. Bu, anlık geri bildirim sağlar ve küçük hataların bile commit edilmesini engeller.
- CI/CD Pipeline: Her commit’te veya belirli aralıklarla (örneğin gece), daha kapsamlı bir SAST taraması otomatik olarak çalışır. Bulunan zafiyetler JIRA veya benzeri bir issue takip sistemine otomatik olarak kaydedilir. Bu aşamada, pipeline’ı yavaşlatmayacak kadar kısa süren taramalar tercih ederim.
- Staging Ortamı ve QA: Uygulama staging ortamına deploy edildiğinde, DAST taramaları devreye girer. Bu taramalar, uygulamanın tüm fonksiyonlarını kapsayan senaryoları çalıştırır ve runtime zafiyetlerini arar. Benim bir projemde, DAST taraması SAST’a göre belirgin biçimde daha uzun sürdüğü için periyodik olarak çalışırdı. Bu, DevSecOps Pipeline Güvenlik Otomasyonu yazımda detaylandırdığım bir yaklaşımdı.
Bu entegrasyon, güvenlik kontrollerini geliştirme sürecine “sol tarafa” (shift-left) taşımak anlamına gelir. Güvenliği sonradan eklenen bir adım olmaktan çıkarıp, tüm sürecin ayrılmaz bir parçası haline getirir. Bu sayede, güvenlik açıkları maliyeti en düşük seviyede düzeltilir.
Karar Verirken Nelere Dikkat Edilmeli?
SAST ve DAST araçlarını seçerken ve entegre ederken bazı trade-off’lar ve dikkat edilmesi gereken noktalar var. Benim tecrübelerime göre en önemlileri şunlar:
- Yanlış Pozitifler (False Positives): SAST araçları, kodun bağlamını tam olarak anlayamadığı için bazen yanlış pozitifler üretebilir. Bu durum, geliştiricilerin güvenlik uyarılarına karşı “alarm yorgunluğu” yaşamasına neden olabilir. DAST’ta bu oran genellikle daha düşüktür çünkü çalışan uygulamayı test eder. Benim bir projemde, SAST’tan gelen uyarıların azımsanmayacak bir kısmı yanlış pozitifti ve bunları manuel olarak elememiz gerekti. Bu, zaman kaybına yol açtı.
- Tarama Süresi ve Performans: Özellikle büyük kod tabanları için SAST taramaları zaman alabilir. DAST taramaları da uygulamanın karmaşıklığına ve taranan endpoint sayısına göre uzayabilir. CI/CD pipeline’ında, bu sürelerin makul sınırlar içinde kalması için sürekli optimizasyon yapmaya çalıştım. Örneğin, sadece değişen kod parçalarını tarayan artımlı (incremental) SAST taramaları kullanmak işe yaradı.
- Entegrasyon Kolaylığı: Seçtiğiniz araçların mevcut CI/CD pipeline’ınızla, IDE’nizle ve issue takip sistemlerinizle ne kadar kolay entegre olabildiği önemli. İyi bir API desteği veya hazır eklentiler, entegrasyon maliyetini düşürür.
- Kapsam ve Dil Desteği: SAST araçları belirli programlama dillerine odaklanırken, DAST araçları dil bağımsızdır. Kullandığınız teknoloji yığınına uygun araçları seçmek kritik. Örneğin C# ve Python’un birlikte kullanıldığı karma bir sistemde, her iki dil için de destek veren SAST araçları bulmak ek bir araştırma gerektirebilir.
- Maliyet: Hem açık kaynaklı hem de ticari SAST/DAST çözümleri mevcut. Ticari çözümler genellikle daha fazla özellik ve destek sunarken, maliyetleri de yüksek olabilir. Kendi VPS’imde yönettiğim küçük projelerimde açık kaynaklı
Bandit(Python için SAST) veOWASP ZAP(DAST) gibi araçları kullandım. Büyük kurumsal projelerde ise genellikle ticari çözümlere yönelmek durumunda kaldık.
Bu faktörleri göz önünde bulundurarak, projenizin ihtiyaçlarına ve bütçesine en uygun kombinasyonu seçmek, güvenlik stratejinizin başarısı için anahtar olacaktır.
Sonuç: Güvenlik Bir Süreçtir, Tek Seferlik Bir Eylem Değil
Uygulama güvenliği, tek bir araç veya tek bir test ile sağlanabilecek bir durum değildir. SAST ve DAST, her ikisi de uygulamanın farklı katmanlarında ve farklı yaşam döngüsü aşamalarında kritik roller oynar. Gördüğüm en büyük ders, güvenliğin sürekli bir süreç olduğu ve geliştirme sürecine baştan sona entegre edilmesi gerektiğidir.
“Hangisi önce gelmeli?” sorusunun cevabı, benim için her zaman “Her ikisi de, ama doğru zamanda” olmuştur. SAST ile kod seviyesindeki hataları erkenden yakalamak, DAST ile de çalışan uygulamanın dışarıya dönük yüzündeki zafiyetleri tespit etmek, kapsamlı bir güvenlik duruşu sağlar. Unutmayın, bir güvenlik ihlali, şirketin itibarına ve finansal durumuna ciddi zararlar verebilir. Bu yüzden, güvenlik yatırımı asla göz ardı edilmemelidir. Bir sonraki adım, bu araçları kendi CI/CD pipeline’ınıza nasıl entegre edeceğinizi planlamak olmalı.