Merhaba, önceki derslerimizde bir kod tabanının haritasını çıkarmayı, kritik giriş ve çıkış noktalarını belirlemeyi ve son olarak da servisler arası örtük güven ilişkilerini analiz ederek istismar edilebilir varsayımları ortaya çıkarmayı öğrendik. Artık bir sistemin mimari düzeydeki güvenlik duruşunu ve potansiyel zayıf halkalarını değerlendirebilecek bir bakış açısına sahibiz.
Ancak, gerçek dünyadaki devasa kod tabanlarıyla karşılaştığımızda yeni bir sorunla yüzleşiriz: zaman. Milyonlarca satır kodu satır satır incelemek imkansızdır. Bu derste, bir güvenlik analistinin en değerli yeteneklerinden birini, yani sınırlı zamanda maksimum etkiyi yaratma sanatını ele alacağız. Öğrenme hedefimiz, review kapsamını saldırı yüzeyi, kod karmaşıklığı ve değişiklik geçmişine göre nasıl önceliklendireceğimizi öğrenmektir. Bu stratejik yaklaşım, uzman gözünüzü en verimli av sahalarına odaklamanızı sağlayacak.
Önceliklendirme Üçgeni: Nereye Bakmalı?
Etkili bir kod incelemesi, körlemesine bir arayış değil, bilinçli bir keşif sürecidir. Eforumuzu nereye yoğunlaştıracağımızı belirlemek için üç temel kritere dayanırız:
- Saldırı Yüzeyi ve İş Riski: Kodun hangi kısımları saldırganlara açık? Bu kısımlar iş açısından ne kadar kritik?
- Kod Karmaşıklığı: Kodun hangi kısımlarını anlamak ve doğrulamak zor? Karmaşıklık, hataların saklandığı yerdir.
- Değişiklik Geçmişi (Code Churn): Kodun hangi kısımları en sık değişiyor? Sürekli değişen kod, yeni zafiyetlerin doğduğu yerdir.
Bu üç unsuru bir araya getirerek, bir kod tabanının en riskli bölgelerini, yani "sıcak noktaları" (hotspots) belirleyebiliriz.
1. Saldırı Yüzeyi ve İş Riski ile Önceliklendirme
Bir kod tabanının tüm giriş noktaları eşit yaratılmamıştır. Önceliğimiz, en yüksek riski taşıyan özellikler olmalıdır. Bu, hem teknik bir saldırı yüzeyi analizi hem de iş mantığına dayalı bir risk değerlendirmesi gerektirir.
- İş Kritikliği: Hangi özellikler para, hassas kişisel veriler (PII), sağlık bilgileri veya kimlik doğrulama/yetkilendirme gibi temel işlevleri yönetiyor? Bir ödeme ağ geçidi, bir kullanıcı profili düzenleme ekranından her zaman daha yüksek önceliğe sahiptir.
- Erişilebilirlik: Hangi API endpoint'leri internete açık? Hangileri sadece dahili ağdan erişilebilir? Önceki dersimizde öğrendiğimiz gibi, dahili servisler de hedeftir, ancak herkese açık endpoint'ler ilk savunma hattıdır ve daha yoğun bir inceleme gerektirir.
Bu risk değerlendirmesini yapılandırmak için endüstri standardı bir çerçeve olan OWASP Uygulama Güvenliği Doğrulama Standardı (ASVS)'ndan faydalanabiliriz. ASVS, bir uygulamanın risk profiline göre farklı doğrulama seviyeleri tanımlar.
[PDF] OWASP Uygulama Güvenliği Doğrulama Standardı 4.0
Bu doküman, bir uygulamanın güvenlik gereksinimlerini risk seviyesine göre nasıl sınıflandıracağınızı anlamak için temel bir çerçeve sunar. Bu, kod incelemesi kapsamını belirlerken size yol gösterecektir.
Lütfen "ASVS Kullanımı" başlığı altındaki Doğrulama Seviyeleri ve Pratik Uygulama bölümlerini okuyun. Özellikle Seviye 1 (Fırsatçı), Seviye 2 (Standart) ve Seviye 3 (Gelişmiş) arasındaki farklara odaklanın. Hangi tür uygulamaların hangi seviyeye karşılık geldiğini anlamak, inceleme derinliğinizi belirlemenize yardımcı olur. Örneğin, bir finansal işlem uygulaması Seviye 3 iken, bir blog sitesi Seviye 1 olabilir. Ardından, V1: Mimari, Tasarım ve Tehdit Modelleme bölümündeki Kontrolün Amacı ve Güvenli Yazılım Geliştirme Yaşam Döngüsü alt başlıklarını inceleyin. Bu kısım, tehdit modellemesi ve güven sınırlarının belgelenmesi gibi mimari düzeydeki kontrollerin, saldırı yüzeyini anlamadaki önemini vurgular. Bu, sizin tecrübenizle doğrudan örtüşen, "büyük resmi görme" yeteneğidir.
ASVS'yi kullanarak bir uygulamanın Seviye 3 (en kritik) olduğunu belirledikten sonra, bu uygulamanın kimlik doğrulama, yetkilendirme, ödeme işlemleri gibi en hassas modüllerine odaklanırız. Bu modüller, kod incelemesi için ilk adaylarımızdır.
2. Kod Karmaşıklığı ve Değişiklik Geçmişi: Sıcak Noktaları (Hotspots) Bulmak
Saldırı yüzeyini daralttıktan sonra bile elimizde on binlerce satır kod olabilir. Bir sonraki adım, bu kodlar içinde en çok hata barındırma potansiyeline sahip olanları bulmaktır. Burada devreye kod metrikleri girer.
Kod Karmaşıklığı (Code Complexity): Matematik altyapınızdan aşina olabileceğiniz gibi, karmaşıklık genellikle daha fazla hata anlamına gelir. Yazılımda bu, genellikle siklomatik karmaşıklık (cyclomatic complexity) gibi metriklerle ölçülür. Derinlemesine iç içe geçmiş koşullar, uzun fonksiyonlar ve karmaşık mantık akışları içeren kod blokları, hem geliştiricilerin hem de güvenlik analistlerinin gözünden kaçabilecek mantık hataları için ideal saklanma yerleridir.
Değişiklik Geçmişi (Code Churn): Bir dosyanın ne sıklıkla değiştirildiği (commit sayısı), o kod parçasının ne kadar "canlı" olduğunun bir göstergesidir. Sık değişen kod iki anlama gelebilir:
- Aktif olarak geliştirilen ve sürekli yeni özellikler eklenen bir alan. Bu, aceleyle yazılmış kod ve yeni hatalar anlamına gelebilir.
- Tasarımı sorunlu, anlaşılması zor ve sürekli "düzeltme" gerektiren bir alan. Bu da temelden kusurlu bir mantığın işareti olabilir.
Bu iki metriği birleştirdiğimizde, en tehlikeli alanları ortaya çıkarırız: hem karmaşık hem de sık değişen kod. Bu bölgeler, zafiyetlerin filizlendiği "sıcak noktalardır".

Bu analizi yapmak için git log komutları ve lizard gibi kod karmaşıklığı ölçen araçlarla kendi betiklerinizi yazabilirsiniz. Ayrıca, CodeScene gibi gelişmiş araçlar bu tür analizleri otomatik olarak yapar ve görselleştirir.

Bu metriklerin neden önemli olduğuna dair daha derin bir teorik bakış açısı için aşağıdaki metni inceleyebilirsiniz. Bu kaynak, büyük ve uzun ömürlü sistemlerde yapılan değişikliklerin neden öngörülemeyen riskler yarattığını ve bu risklerin nasıl yönetilebileceğini ele alıyor.
Dağıtım Öncesi Değişiklik Etkisini Tahmin Etmek için Kod İzlenebilirliği
Bu makale, büyük kurumsal sistemlerdeki değişikliklerin neden öngörülemeyen ve genellikle orantısız sonuçlara yol açtığını açıklıyor. Bu, sık değişen ve karmaşık kodun neden riskli olduğunu anlamak için mükemmel bir temel sağlar.
Öncelikle, Değişimin Neden Öngörülemez Olduğu bölümünü okuyun. Bu bölüm, uzun ömürlü kod tabanlarında biriken "gizli bağımlılıklar" ve zamanla orijinal mimariden sapan "yürütme yolları" gibi kavramları açıklar. Ardından, Yürütme Yolları başlıklı bölüme geçin. Bu kısım, statik kod yapısının ötesinde, sistemin çalışma zamanında nasıl davrandığını (kontrol akışı ve veri akışı) anlamanın önemini vurgular. Bu, bizim manuel analiz yaklaşımımızla doğrudan uyumludur. Bağımlılık Zincirleri bölümü, bir değişiklik etkisinin sadece değiştirilen kodla sınırlı kalmayıp, dolaylı ve zamansal bağımlılıklar aracılığıyla nasıl yayıldığını anlatır. Son olarak, Küçük Değişikliklerin Büyük Etkileri bölümünü inceleyin. Bu bölüm, zamanlama, sıralama ve yapılandırma gibi faktörlerin, görünüşte küçük bir kod değişikliğinin etkisini nasıl katlayarak artırabileceğini gösterir. Bu, değişiklik geçmişini analiz ederken neden dikkatli olmamız gerektiğini açıklar.
Hepsini Birleştirmek: Pratik Bir Strateji
Artık elimizde güçlü bir önceliklendirme stratejisi var:
- Yukarıdan Aşağıya (Risk Odaklı): Önce iş kritikliği ve ASVS seviyeleri ile en önemli modülleri belirle.
- Aşağıdan Yukarıya (Veri Odaklı): Ardından, bu kritik modüller içinde kod metriklerini (karmaşıklık ve churn) kullanarak en riskli "sıcak nokta" dosyalarını bul.
Örnek İş Akışı:
- İnceleyeceğimiz uygulamanın bir e-ticaret platformu olduğunu varsayalım. Ödeme ve kullanıcı yönetimi modülleri, ASVS Seviye 3 gerektirir. İlk odak noktamız bu modüllerdir.
- Bu modüllere ait kaynak kod dosyaları üzerinde bir "churn vs. complexity" analizi yaparız.
- Analiz sonucunda,
PaymentService.jsdosyasının hem çok karmaşık (çok sayıda if/else bloğu içeriyor) hem de son altı ayda 80'den fazla kez değiştirildiğini görürüz. - İşte bu!
PaymentService.js, manuel kod incelemesi için ilk ve en önemli hedefimizdir.
Bu "uzman gözüyle" anında önceliklendirme sezgisini geliştirmek için aşağıdaki videoyu izleyebilirsiniz. Videodaki amaç, gösterilen zafiyetleri tekrar öğrenmek değil, bir uzmanın küçük kod parçalarında bile anında en şüpheli ve riskli kısımlara nasıl odaklandığını gözlemlemektir.
ChatGPT vs Hacker ! SonarSource Kaynak Kod Analizi ile Zafiyet Tespiti Challenge'ı
Bu videoda Mehmet İnce, farklı dillerdeki küçük kod challenge'larını çözüyor. Her bir challenge'da, kodun tamamını okumak yerine sezgisel olarak en riskli noktalara nasıl odaklandığına dikkat edin. Bu, bizim büyük ölçekte yapmaya çalıştığımız önceliklendirmenin mikro bir yansımasıdır.
PHP Token Zafiyeti: bu bölümde, analizin doğrudan kriptografik olarak güvenli olmayan mt_rand() ve sunucu zamanına bağlı time() fonksiyonlarına odaklandığını görün. Bunlar, güvenlik açısından bilinen "tehlikeli" desenlerdir. Java Stored XSS: bu kısımda, analist verinin akış yoluna odaklanır: kullanıcıdan alınıyor, bir replace işleminden geçiyor ve sonra bir normalizer'a giriyor. Bir temizleme ve bir normalleştirme adımının etkileşimi, potansiyel bir karmaşıklık ve risk noktasıdır. C# Open Redirect: bu örnekte odak noktası anında regex ile yapılan doğrulama ve hemen ardından gelen HttpClient çağrısıdır. Bir "girdi doğrulama" mekanizmasını takip eden "tehlikeli bir işlem" (sunucu tarafı istek yapma) klasik bir sıcak noktadır. JavaScript Auth Bypass: burada, analist URL'in startsWith('/api') ile kontrol edildiği satıra odaklanıyor. Kimlik doğrulama gibi kritik bir kararın basit bir string karşılaştırmasına bağlanması, her zaman şüpheyle yaklaşılması gereken bir desendir. Python Kripto Zafiyeti: bu son bölümde, analiz doğrudan AES.MODE_ECB kullanımına odaklanıyor. Bu, kriptografi dünyasında güvensiz olduğu bilinen bir konfigürasyondur. Karmaşık ve ezoterik konular genellikle hata yapmaya daha müsaittir ve önceliklendirilmelidir.
Sonuç
Bu derste, devasa bir kod tabanında kaybolmak yerine, çabalarımızı en riskli ve en verimli alanlara nasıl odaklayacağımızı öğrendik. Stratejik önceliklendirme, ileri seviye bir güvenlik analistinin en önemli becerilerinden biridir.
Temel Çıkarımlar:
- Etkili bir kod incelemesi, kapsamı doğru belirlemekle başlar. Her şeyi incelemek mümkün değildir.
- Önceliklendirme stratejimiz üç temel üzerine kuruludur: Saldırı Yüzeyi/İş Riski, Kod Karmaşıklığı ve Değişiklik Geçmişi (Churn).
- Bu kriterleri birleştirerek, zafiyet barındırma olasılığı en yüksek olan sıcak noktaları (hotspots) belirleriz.
- OWASP ASVS gibi çerçeveler iş riskini değerlendirmek için,
git loggibi araçlar ise kod metriklerini toplamak için kullanılabilir.
Önceki derslerde bir kod sisteminin haritasını çıkardık, giriş ve çıkışlarını belirledik, servisler arası güveni analiz ettik ve bugün de nereye odaklanacağımızı öğrendik. Artık tam donanımlı bir şekilde ava çıkmaya hazırız.
Bir sonraki modülümüz olan "Manuel Veri Akışı ve Taint Analizi" ile birlikte, belirlediğimiz bu sıcak noktaların içinde zafiyetleri nasıl avlayacağımızın teknik detaylarına ineceğiz. Kullanıcıdan gelen "kirli" (tainted) veriyi, sisteme girdiği noktadan tehlikeli bir hedefe (sink) ulaşana kadar manuel olarak nasıl izleyeceğimizi öğreneceğiz. Bu ders, o temel beceriyi nerede uygulayacağımızın stratejik planını çizdi.