← İçindekiler Güvenli Kodlama EğitimiGüvenli Kodlama Temelleri
2017’de Equifax, dünyanın en büyük kredi derecelendirme şirketlerinden biri, 147 milyon kişinin verisini sızdırdı. Sebep? Apache Struts kütüphanesinde bilinen bir açık (CVE-2017-5638) iki ay önce yaması çıkmıştı ama kimse uygulamamıştı. Kod yazıldı, test edildi, üretildi. Güvenlik hiçbir aşamada sorulmadı. Sonuç: 1.4 milyar dolar ceza, CEO istifası, 147 milyon kişinin T.C. kimlik numarası, adresi ve kredi kartı bilgisi sızdırıldı.
Özlü kural: Güvenlik bir özellik değil, bir süreçtir. Kodun sonuna eklenen bir güvenlik modülü değil, her satırın yazılış şeklidir.
Hızlı ipucu: Kod deposunda grep -ri "os.system\|eval(\|innerHTML" . komutunu çalıştır. Çıkan her satır, potansiyel bir güvenlik açığıdır.
51.1 Güvenli SDLC Nedir?
SDLC (Yazılım Geliştirme Yaşam Döngüsü), yazılımın doğumundan ölümüne kadar geçen sürecidir. Geleneksel SDLC’de güvenlik, test aşamasının sonuna bırakılır. Ekip geliştirir, test eder ve son güne “siber güvenlik ekibi gelip bir şeyler bulur” diye bekler. Bu yaklaşım artık ölüdür.
Güvenli SDLC, güvenliği sürecin her aşamasına gömer:
| Aşama | Güvenlik Aktivitesi |
|---|---|
| Gereksinim | Güvenlik gereksinimleri topla, tehdit modellemesi planla |
| Tasarım | Tehdit modellemesi yap, mimari risk analizi |
| Geliştirme | Güvenli kodlama standartları, statik analiz (static analysis) |
| Test | SAST, DAST, sızma testi (penetrasyon testi) |
| Dağıtım | Güvenlik yapılandırma kontrolü, gizli anahtar taraması (secret scanning) |
| Bakım | Yama yönetimi, olay müdahale planı |
Güvenli SDLC’nin en bilinen çerçevesi Microsoft SDL’dir. Tehdit Modelleme Çerçeveleri bölümünde SDL’nin detaylarını bulabilirsin.
Maliyet farkı: Bir güvenlik hatasını gereksinim aşamasında düzeltmenin maliyeti 1 birimse, test aşamasında 30 birim, üretime çıktıktan sonra 300 birim. Tasarım aşamasında yapılan bir hata, üretime kadar fark edilmezse maliyeti 300 katına çıkar.
Saldırgan gözüyle: Saldırgan, kodundaki açığı aramaz. Senin “daha sonra düzeltiriz” diye ertelediğin teknik borcu arar. Bir TODO yorumu, bir // FIXME, bir kapalı Jira bileti: hepsi saldırgana “burada bir açık var” der.
Ekip, yeni bir ödeme sayfasını iki haftada yayınlamak (shipping) zorunda. Tasarım aşamasında tehdit modellemesi atlandı. Kod yazıldı, test edildi, üretime alındı. İki ay sonra bir siber güvenlik araştırmacısı, ödeme sayfasında SQL injection (SQL enjeksiyonu) açığı buldu. Şirketin veri ihlali maliyeti: 500.000 TL. Tehdit modellemesi yapsalardı 2 saat sürecek, maliyet 0 TL olacaktı. Şimdi açığı kapatmak, müşterilere bildirim göndermek, KVKK cezası ödemek ve itibar onarımıyla uğraşmak zorundalar.
51.2 Sola Kaydırma (Shift-Left) Felsefesi
Sola kaydırma (shift-left), güvenliği sürecin soluna, yani en başına çekmektir. Geleneksel süreçte güvenlik sağdadır (en sonda). Sola kaydırma felsefesi şunu söyler: hata ne kadar erken yakalanırsa düzeltme o kadar ucuz olur.
| Ne zaman bulundu? | Maliyet | Neden |
|---|---|---|
| Gereksinim/Tasarım | 1x | Kod yazılmadı, sadece plan değişti |
| Geliştirme | 5x | Kod yeniden yazılacak |
| Test | 30x | Kod yazıldı, test edildi, belgelendi; hepsi değişecek |
| Üretim | 300x | Müşteri etkilenir, veri sızar, ceza gelir, itibar çöker |
Geliştiricinin sorumluluğu sadece çalışan kod yazmak değildir. Güvenli kod yazmaktır. Güvenlik ekibi denetleyen değil, danışman rolüne geçmelidir. Geliştirici güvenli kodu yazmayı bilirse, denetim gereksiz hale gelir.
Sola kaydırmanın başarısız olduğu en yaygın senaryo: geliştiriciye “güvenli kod yaz” denir ama eğitim verilmez. Geliştirici hangi açıkları nasıl yazdığını bilmiyorsa, farkında olmadan her gün yeni açık üretir. Eğitim şarttır.
51.3 Güvenli Tasarım Prensipleri
Güvenlik tasarımının sekiz klasik ilkesi (Saltzer-Schroeder, 1975) bugün hâlâ geçerli:
1. En Az Yetki (Least Privilege): Bir kullanıcı, işlem veya program, görevini yerine getirmek için yalnızca gereken en düşük yetkiye sahip olmalıdır. Bir raporlama servisinin veritabanına yazma yetkisi olmamalıdır. Sadece okuma yeterlidir.
2. Derinlemesine Savunma (Defense in Depth): Tek bir savunma hattına güvenme. Bir saldırgan güvenlik duvarını geçerse, kimlik doğrulama durdurmalı. Kimlik doğrulamayı geçerse, erişim kontrolü durdurmalı. Erişim kontrolünü geçerse, veri şifreli olmalı. Katmanlar çoğaldıkça saldırganın işi zorlaşır.
3. Güvenli Varsayılanlar (Fail-Safe Defaults): Bir şeyler ters gittiğinde sistem en güvenli duruma düşmelidir. Erişim kararsız kalırsa, varsayılan “reddet” olmalıdır. Bir hata durumunda “izin ver” değil “izin reddet” davranışı benimsenmelidir.
4. Tam Arabuluculuk (Complete Mediation): Her erişim isteği, her seferinde yetki kontrolünden geçmelidir. Kullanıcı bir kez giriş yaptığında, “giriş yaptı” diye bir bayrak saklanıp sonraki tüm isteklerde bu bayrağa güvenilmemelidir. Her istekte yetki yeniden kontrol edilmelidir.
5. Mekanizma Ekonomisi (Economy of Mechanism): Tasarım ne kadar basitse, açıklar o kadar az olur. Karmaşık sistemlerde açık bulunmaz, sadece açık patlar. Güvenlik tasarımında basitlik, karmaşıklıktan her zaman üstündür.
6. Açık Tasarım (Open Design): Güvenlik, sistemin gizli olmasına değil, doğru tasarlanmasına dayanmalıdır. “Güvenlik belirsizliğe dayanır” (security by obscurity) yaklaşımı çürümüştür. Açık kaynaklı şifreleme algoritmaları (AES, RSA) herkes tarafından bilinir ama yine de kırılamaz.
7. Görev Ayrımı (Separation of Duties): Kritik bir işlem tek kişinin onayına bırakılmamalıdır. Para transferi, veri silme, yönetici yetkisi verme gibi işlemlerde iki kişinin onayı istenmelidir. Bu, tek bir içeriden tehdidin sistemi çökertmesini engeller.
8. Psikolojik Kabul Edilebilirlik (Psychological Acceptability): Güvenlik önlemleri kullanımı zorlaştırdığında insanlar onları atlatmaya çalışır. Günde 10 kez karmaşık parola isteyen bir sistem, kullanıcının parolayı kağıda yazmasına neden olur. Güvenlik, kullanım kolaylığıyla dengelenmelidir.
- Her servise sadece gereken en düşük yetkiyi ver
- Güvenliği tasarım aşamasında planla, sonraya bırakma
- Hata durumunda sistemi en güvenli duruma düşür
- Savunmayı birden fazla katmana yay
- Güvenlik belirsizliğine (obscurity) güven
- Karmaşık mimariyi "daha güvenli" san
- Güvenliği sadece test aşamasına bırak
- Geliştiriciye güvenli kod eğitimi vermeden "güvenli yaz" de
51.4 Kod İnceleme (Code Review) Kültürü
Kod inceleme (code review), başka bir geliştiricinin (veya güvenlik uzmanının) yazılan kodu güvenlik açısından denetlemesidir. Otomatik araçlar (SAST) birçok hatayı yakalar ama bazı hatalar sadece insan gözüyle tespit edilir. Örneğin: iş mantığı hatası, yetki kontrolünün yanlış yerde yapılması, yarış durumu (race condition).
Güvenlik odaklı kod inceleme kontrol listesi:
- Girdi doğrulama (input validation): Dışarıdan gelen her veri doğrulanıyor mu? Tip, uzunluk, format kontrolü var mı?
- Çıktı kodlama (output encoding): Veri ekrana basılmadan önce kodlanıyor mu? (XSS savunması)
- Kimlik doğrulama (authentication): Doğru uygulanmış mı? Parola hash’leniyor mu?
- Yetkilendirme (authorization): Her istekte yetki kontrolü yapılıyor mu? IDOR açığı var mı?
- Gizli anahtar yönetimi (secret management): Kodda, commit mesajında, loglarda gizli anahtar (secret) var mı?
- Hata yönetimi (error handling): Hata mesajları hassas bilgi sızdırıyor mu? Yığın izi (stack trace) kullanıcıya gösteriliyor mu?
- Bağımlılıklar (dependencies): Yeni eklenen kütüphane bilinen bir açığa sahip mi?
- Şifreleme (crypto): Doğru algoritma kullanılıyor mu? Anahtar yönetimi doğru mu?
Kod incelemeyi “saldırgan simülasyonu” olarak düşün. Her kod inceleme isteğinde (pull request) soru şu: “Saldırgan bu kodu nasıl sömürür?” Bu düşünce yapısı, en etkin güvenlik inceleme yöntemidir.
51.5 Güvenlik Standartları ve Sınıflandırmaları
Güvenlik dünyasında ortak bir dil oluşturmak için standartlar geliştirilmiştir:
CWE (Ortak Zafiyet Sınıflandırması): Yazılım güvenlik zafiyetlerini sınıflandıran bir katalogdur. Her zafiyet tipine bir CWE-ID verilir. Örneğin CWE-89 SQL Injection, CWE-79 XSS, CWE-78 işletim sistemi komut enjeksiyonudur. MITRE Corporation tarafından yönetilir. CWE, “bu tür hata ne denir?” sorusunu cevaplar.
CVE (Ortak Güvenlik Açığı Kaydı): Bilinen, somut güvenlik açıklarının kaydıdır. Her açığa bir CVE-ID verilir (örneğin CVE-2021-44228 Log4Shell). “Hangi kütüphane, hangi sürümde hangi açığa sahip?” sorusunu cevaplar. NVD (Ulusal Güvenlik Açığı Veritabanı) üzerinden erişilir.
CVSS (Ortak Güvenlik Açığı Puanlama Sistemi): Bir CVE’nin kritikliğini 0-10 arası puanlar. CVSS 9-10 kritik, 7-8.9 yüksek, 4-6.9 orta, 0-3.9 düşüktür. Önceliklendirme için kullanılır: “Önce hangi açığı kapatmalıyım?” sorusunu cevaplar.
OWASP (Açık Dünya Geneli Uygulama Güvenliği Projesi): Web uygulama güvenliği için en bilinen sivil topluluk kuruluşu. OWASP Top 10 (en kritik 10 web uygulama riski), OWASP ASVS (Uygulama Güvenliği Doğrulama Standardı) gibi kaynaklar yayınlar.
NIST (Ulusal Standartlar ve Teknoloji Enstitüsü): ABD standart kuruluşu. NIST 800-53 (güvenlik kontrolleri), NIST 800-63B (kimlik doğrulama rehberi) gibi yayınları, kurumsal güvenlik politikalarının temelini oluşturur.
CERT (Bilgisayar Acil Müdahale Ekibi): Güvenlik olaylarına müdahale eden ve güvenlik duyuruları yayınlayan ekiplerdir. CERT/CC (Carnegie Mellon), US-CERT, TR-CERT gibi ulusal ve uluslararası CERT’ler vardır. Yeni açıkların duyurusu ve acil müdahale süreçlerini yönetirler.
CWE, CVE ve CVSS arasındaki ilişki nedir?
CWE zafiyet türünü tanımlar (örneğin CWE-89 SQL Injection). CVE, o türün somut bir örneğidir (örneğin CVE-2023-1234, Acme CMS 2.1’de SQL injection açığı). CVSS ise o CVE’nin kritikliğini puanlar (örneğin CVSS 9.8 kritik). Yani: CWE “ne tür hata?”, CVE “hangi ürün, hangi sürümde?”, CVSS “ne kadar acil?” sorularını cevaplar.
SBOM nedir, neden önemli?
SBOM (Yazılım Bileşen Listesi), bir yazılımın kullandığı tüm bileşenlerin (kütüphaneler, sürümler, lisanslar) listesidir. Tıpkı bir yemek tarifindeki malzeme listesi gibi. Yeni bir CVE yayınlandığında SBOM’un varsa, “bu kütüphaneyi kullanıyor muyum?” sorusunu saniyeler içinde cevaplarsın. SBOM yoksa, tüm projeyi tarayıp manuel arama yapmak gerekir. 2024’ten beri ABD federal alımlarında SBOM zorunludur. Güvenlik Testi ve DevSecOps bölümünde detaylıca inceleyeceğiz.
STRIDE ile OWASP Top 10 farkı nedir?
STRIDE bir tehdit modelleme çerçevesidir: “sisteme kim, nasıl saldırabilir?” sorusuna sistematik cevap arar. OWASP Top 10 ise bir risk listesidir: “web uygulamalarında en kritik 10 sorun nedir?” STRIDE tasarım aşamasında mimariyi analiz etmek için, OWASP ise geliştirme aşamasında kodun kalitesini ölçmek için kullanılır. İkisi birbirini tamamlar.
Pazartesi sabahı bir e-posta geldi: “Log4j 2.14.1 sürümünde kritik açık (CVE-2021-44228, CVSS 10.0).” Ekipten biri panikle “tüm sistemleri kapatmalı mıyız?” diyor. Doğru yaklaşım: önce SBOM’a bak, hangi sistemlerin Log4j kullandığını tespit et. Sonra etkilenen sistemleri önceliklendir: internete açık olanlar önce. Yama uygula, test et, dağıt. Panik değil, süreç. CVSS 10.0 “kritik” demektir ama panik demek değildir. Sistematik önceliklendirme her zaman panikten hızlıdır.
Gerçek olay: 2017’de Equifax, 147 milyon kişinin adını, adresini, sosyal güvenlik numarasını ve kredi kartı bilgisini sızdırdı. Sebep: Apache Struts çatısındaki (framework) CVE-2017-5638 açığı. Yama iki ay önce yayınlanmıştı ama uygulanmamıştı. Güvenli SDLC süreci olmayan bir ekip, “yama çıktı, uygulayalım” diye kimse sormadı. Sonuç: 1.4 milyar dolar ceza, CEO istifası, 147 milyon kişinin mahremiyeti çöptü. Tek bir yamanın uygulanmaması, şirketin sonu oldu.
- Güvenlik gereksinimleri proje başında toplandı
- Tasarım aşamasında tehdit modellemesi yapıldı
- Geliştiricilere güvenli kodlama eğitimi verildi
- Her kod inceleme isteğinde (PR) güvenlik odaklı inceleme yapılıyor
- En az yetki prensibi tüm servislere uygulandı
- SBOM oluşturuldu ve güncel tutuluyor
- CVE takip süreci tanımlandı (kim, nasıl, ne zaman)
- Güvenlik standartları (OWASP, NIST) referans alınıyor
Benzetme: Güvenli kodlama, bir binanın temeline benzer. Temel atılmadan çatı kurulmaz. Çatıdan sızan suyu tamir etmek, temelden başlayan bir çatlağı tamir etmekten her zaman daha kolaydır ama ikisi de temel sağlam değilse anlamsızdır. Güvenliği “sonradan ekleyeceğiz” demek, binayı bitirip sonra temel kazmaya çalışmaktır.