Güvenli yazılım geliştirme: SDLC, tasarım ilkeleri ve tehdit modelleme
Güvenliği koda sonradan eklemek yerine yaşam döngüsünün her aşamasına koymayı, Saltzer-Schroeder tasarım ilkelerini, STRIDE ile tehdit modellemeyi ve güvenlik gereksinimlerini öğrenirsin. Sınavda senaryo verip 'hangi ilke ihlal edildi' diye sorulur.
Güvenlik açıklarının çoğu “kötü kodlanmış satır” değil, kötü verilmiş kararlardır: kimse yetkiyi düşünmemiştir, hata durumunda ne olacağı tanımlanmamıştır, admin paneli internete açık bırakılmıştır. Bu hafta güvenliği yazılım yaşam döngüsünün (SDLC) içine nasıl yerleştireceğini öğreniyorsun. Sınavda tipik soru şöyle: kısa bir senaryo verilir, “which principle is violated?” ya da “which STRIDE category?” diye sorulur. Bir de DREAD veya risk hesabı gelebilir.
Altın kurallar:
- Güvenlik bir aşama değil, her aşamadır. Gereksinimde başlar, bakımda bitmez.
- Varsayılan cevap “hayır”. Emin değilsen erişimi reddet.
- Her erişimi denetle. Bir kez kontrol edip unutmak yetmez.
- Tehditleri sistematik bul. STRIDE harf harf sorgulatır, akla gelmeyeni yakalar.
- Riski sayıyla sırala. Her şeyi aynı anda düzeltemezsin.
Güvenli SDLC (secure software development life cycle)
Klasik SDLC aşamalarına her birinde yapılacak güvenlik işini ekleyince güvenli SDLC elde edilir. Microsoft SDL, OWASP SAMM, BSIMM bu fikrin farklı çerçeveleridir.
| Aşama | Güvenlik işi | Çıktı |
|---|---|---|
| Gereksinim (requirements) | güvenlik gereksinimleri, misuse case, uyum (KVKK/GDPR) | ölçülebilir gereksinim listesi |
| Tasarım (design) | tehdit modelleme, saldırı yüzeyi analizi, güvenli mimari | DFD + tehdit listesi + önlemler |
| Gerçekleştirme (implementation) | güvenli kodlama standartları, kod inceleme, SAST | temiz statik analiz raporu |
| Test (verification) | DAST, fuzzing, penetrasyon testi | bulgu listesi, kapanmış açıklar |
| Yayın (release) | son güvenlik incelemesi, olay müdahale planı | onay |
| Bakım (maintenance) | yama yönetimi, izleme, bağımlılık takibi | güncel sistem |
Neden en başta? Bir tasarım hatasını tasarım aşamasında düzeltmek bir diyagram değişikliğidir. Aynı hata canlı sistemde bulunursa kod, veri göçü, müşteri bildirimi ve itibar kaybı gelir. Literatürdeki “geç bulunan hatanın maliyeti katlanır” eğrisi güvenlik için daha da diktir.
TUZAK · “Sonunda pentest yaparız” yaklaşımı. Penetrasyon testi bulduğu açığı gösterir ama tasarım hatasını sonradan düzeltmek pahalıdır. Pentest güvenli SDLC’nin yerine geçmez, son kontrolüdür.
Güvenli tasarım ilkeleri (Saltzer & Schroeder)
1975’te Saltzer ve Schroeder’in yazdığı sekiz ilke bugün hâlâ sınavların gözdesi. Yanına sık eklenen derinlemesine savunmayı da koyuyoruz.
| İlke | Bir cümlede | İhlal örneği |
|---|---|---|
| Least privilege | Her bileşen işini yapacak kadar yetkiyle çalışır. | Web sunucusu root ile çalışıyor. |
| Fail-safe defaults | Varsayılan karar reddetmektir; izin açıkça verilir. | Hata olunca erişime izin veren catch. |
| Complete mediation | Her nesneye her erişim denetlenir. | Yetki sadece login’de kontrol ediliyor. |
| Economy of mechanism | Güvenlik mekanizması basit ve küçük olmalı. | 5000 satırlık kendi yazdığın şifreleme. |
| Open design | Güvenlik tasarımın gizliliğine dayanmaz. | “Algoritmamızı kimse bilmiyor, o yüzden güvenli.” |
| Separation of privilege | Kritik iş için birden fazla koşul gerekir. | Tek admin tek başına üretim veritabanını silebiliyor. |
| Least common mechanism | Kullanıcılar arasında paylaşılan mekanizma azaltılır. | Tüm kiracıların aynı geçici dizini paylaşması. |
| Psychological acceptability | Güvenlik kullanılabilir olmalı, yoksa atlatılır. | Her gün değişen 20 karakterlik parola, ekrana yapıştırılan not kâğıtları. |
| Defense in depth | Birbirinden bağımsız birden fazla katman. | Sadece firewall’a güvenip iç ağda şifresiz HTTP. |
Fail-safe defaults: kodda nasıl görünür
// KÖTÜ: servis çökünce herkese izin
boolean canRead(User u, File f) {
try { return acl.allows(u, f, READ); }
catch (Exception e) { return true; }
}
// İYİ: belirsizlikte reddet, olayı kaydet
boolean canRead(User u, File f) {
try { return acl.allows(u, f, READ); }
catch (Exception e) {
log.warn("ACL check failed, denying", e);
return false;
}
}
Aynı fikir firewall kurallarında da geçerli: en sonda “deny all” kuralı olur, izin verilenler tek tek yazılır (allowlist).
Derinlemesine savunma ve olasılık
Bağımsız katmanlarda saldırganın her birini aşma olasılığı çarpılır. Örnek: WAF’ı geçme olasılığı 0.3, uygulama içi doğrulamayı geçme 0.2, veritabanı yetki kısıtını geçme 0.1 ise hepsini geçme olasılığı:
Tek tek zayıf görünen katmanlar birlikte güçlüdür. Ama dikkat: katmanlar aynı zayıflığı paylaşıyorsa (aynı parola, aynı kütüphane) bağımsız değildir ve çarpım geçersiz olur.
İPUCU · İlkeyi bulma yöntemi. Senaryoda “fazla yetki” varsa least privilege, “hata olunca izin” varsa fail-safe, “bir kez kontrol” varsa complete mediation, “gizli algoritma” varsa open design, “tek kişi yeterli” varsa separation of privilege.
Tehdit modelleme (threat modeling)
Tehdit modelleme dört soruya cevap arar: Ne inşa ediyoruz? Ne ters gidebilir? Buna karşı ne yapacağız? İyi bir iş çıkardık mı?
Adım 1: veri akış diyagramı (DFD)
Sistemi dört öğeyle çizersin:
| Öğe | Anlamı | Örnek |
|---|---|---|
| External entity | sistemin dışındaki aktör | kullanıcı, ödeme sağlayıcı |
| Process | veriyi işleyen kod | web uygulaması, API |
| Data store | verinin durduğu yer | veritabanı, log dosyası |
| Data flow | aralarındaki veri hareketi | HTTPS isteği, SQL sorgusu |
Bunların üstüne güven sınırı (trust boundary) çizgileri çizilir: internet ile sunucu arası, uygulama ile veritabanı arası. Tehditlerin çoğu bu sınırları geçen akışlarda ortaya çıkar, çünkü bir taraf diğerinin verisine güvenmemelidir.
Adım 2: STRIDE
Her DFD öğesini altı tehdit kategorisiyle sorgularsın:
| Harf | Tehdit | Bozulan özellik | Tipik önlem |
|---|---|---|---|
| S | Spoofing (kimlik taklidi) | Authentication | güçlü kimlik doğrulama, MFA |
| T | Tampering (kurcalama) | Integrity | MAC, imza, erişim kontrolü |
| R | Repudiation (inkâr) | Non-repudiation | denetim kaydı, dijital imza |
| I | Information disclosure (ifşa) | Confidentiality | şifreleme, en az yetki |
| D | Denial of service | Availability | rate limiting, kaynak kotası |
| E | Elevation of privilege | Authorization | yetki denetimi, sandbox |
Örnek: “Kullanıcı → Login API” akışı için S: başkasının parolasıyla giriş; T: istek yolda değiştirilir; R: kullanıcı girişi inkâr eder; I: hata mesajı “bu e-posta kayıtlı değil” diyerek kullanıcı varlığını sızdırır; D: saniyede binlerce login denemesi; E: istekteki role=admin alanına güvenilmesi.
Adım 3: riskleri sırala
İki yaygın yöntem var.
Risk = olasılık × etki. Olasılık 0-1, etki 1-10:
| Tehdit | Olasılık | Etki | Risk |
|---|---|---|---|
| T1 spoofing | 0.2 | 8 | 1.6 |
| T2 bilgi ifşası | 0.5 | 6 | 3.0 |
| T3 DoS | 0.7 | 3 | 2.1 |
Sıra: T2 > T3 > T1. Etkisi en büyük olan T1 en sonda, çünkü olasılığı düşük.
DREAD. Beş kategori 0-10 puanlanır, ortalaması alınır: Damage, Reproducibility, Exploitability, Affected users, Discoverability.
| Tehdit | D | R | E | A | D | Ortalama |
|---|---|---|---|---|---|---|
| Login formunda SQL injection | 9 | 8 | 7 | 10 | 8 | 8.4 |
| Log dosyası kurcalama | 6 | 5 | 4 | 3 | 5 | 4.6 |
| Ayrıntılı hata mesajları | 3 | 9 | 8 | 6 | 9 | 7.0 |
DREAD öznel olduğu için Microsoft içeride bırakmıştır, ama ders kitaplarında ve sınavlarda hâlâ çıkar. CVSS daha standart bir alternatiftir.
Adım 4: önlem ve doğrulama
Her tehdit için dört seçenek var: azalt (mitigate), ortadan kaldır (özelliği kaldır), devret (sigorta, üçüncü taraf), kabul et (belgelenmiş karar). Sonra önlemin gerçekten çalıştığı testle doğrulanır.
Güvenlik gereksinimleri ve misuse case
Fonksiyonel gereksinim “sistem ne yapmalı” der. Güvenlik gereksinimi “sistem neye izin vermemeli ve nasıl korunmalı” der. İyi bir güvenlik gereksinimi ölçülebilir ve test edilebilir olur.
| Kötü (belirsiz) | İyi (test edilebilir) |
|---|---|
| “Sistem güvenli olmalı.” | “Parolalar bcrypt (cost ≥ 12) ile saklanmalı.” |
| “Brute-force engellenmeli.” | “5 hatalı girişten sonra hesap 15 dakika kilitlenmeli.” |
| “Veri korunmalı.” | “Tüm istemci-sunucu trafiği TLS 1.2+ ile şifrelenmeli.” |
Bu gereksinimleri bulmanın yolu misuse case yazmaktır. Normal use case’te aktör “Müşteri”, senaryo “Hesabına giriş yapar”. Misuse case’te aktör “Saldırgan” (misactor), senaryo “Parola listesini otomatik dener”. Misuse case, use case’i “tehdit eder” (threatens); karşı önlem misuse case’i “azaltır” (mitigates). Her misuse case bir güvenlik gereksinimi doğurur.
TUZAK · Güvenlik gereksinimini fonksiyonel gibi yazmamak. “Admin kullanıcıları silebilir” fonksiyoneldir. Güvenlik tarafı: “Sadece admin rolü silebilir, her silme işlemi kimin yaptığıyla loglanır.” İkinci cümle test edilebilir ve E ile R tehditlerini kapatır.
Sık yapılan hatalar
| Yanlış düşünce | Doğrusu |
|---|---|
| Tehdit modeli test aşamasında yapılır | Tasarımda yapılır, sonra güncellenir |
| Tampering → confidentiality | Integrity. Confidentiality’yi bozan Information disclosure |
| Repudiation → authentication | Non-repudiation; önlem log ve imza |
| Hata olunca erişime izin vermek kullanıcı dostudur | Fail-safe defaults ihlali; varsayılan reddet |
| Login’de bir kez kontrol yeterli | Complete mediation: her erişimde kontrol |
| Gizli algoritma ek güvenliktir | Open design: sadece anahtar gizli olmalı |
| En büyük etkili tehdit önce düzeltilir | Risk = olasılık × etki; olasılığı da hesaba kat |
| “Sistem güvenli olmalı” bir gereksinimdir | Ölçülebilir değil; test edilebilir cümle yaz |
| Katmanlar her durumda olasılık çarpar | Sadece bağımsızlarsa; ortak zayıflık çarpımı bozar |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
A web server process runs as root even though it only needs to read files in /var/www and listen on one port. Which secure design principle is violated?
- Open design
- Least privilege
- Economy of mechanism
- Psychological acceptability
Cevabı göster
Süreç işini yapmak için gereken en az yetkiden fazlasına sahip. En az yetki (least privilege) ilkesi tam olarak bunu yasaklar. Sunucu ele geçirilirse saldırgan root yetkisini de ele geçirir. Doğrusu: ayrı, yetkisiz bir kullanıcıyla çalıştırmak, sadece okuma izni vermek.
In the STRIDE model, a threat of type Tampering violates which security property?
- Confidentiality
- Availability
- Integrity
- Authentication
Cevabı göster
STRIDE her harfi bir özelliğe eşler. Tampering (kurcalama) veriyi ya da kodu izinsiz değiştirmektir, bozulan özellik bütünlük (integrity). Gizlilik bilgi ifşasına (Information disclosure), erişilebilirlik DoS'a, kimlik doğrulama Spoofing'e karşılık gelir.
A user transfers money and later claims 'I never made that transfer', and the system has no way to prove otherwise. Which STRIDE category is this, and which property is missing?
- Spoofing / authentication
- Repudiation / non-repudiation
- Tampering / integrity
- Elevation of privilege / authorization
Cevabı göster
Kullanıcı yaptığı işlemi inkâr ediyor ve sistem kanıtlayamıyor. Bu inkâr (repudiation) tehdididir. Eksik özellik inkâr edilemezlik (non-repudiation). Çözüm: güvenilir, kurcalanamaz denetim kayıtları (audit log) ve gerektiğinde dijital imza.
Security should not depend on keeping the design or the algorithm secret; only keys and passwords should be secret. Which principle is this?
- Open design
- Complete mediation
- Least common mechanism
- Fail-safe defaults
Cevabı göster
Açık tasarım (open design), kriptografideki Kerckhoffs ilkesinin genel hali. Tasarımın gizli kalacağına güvenmek (security through obscurity) zayıftır, çünkü kod sızar, tersine mühendislik yapılır. Gizli kalması gereken sadece anahtar.
A threat is scored with DREAD as Damage = 8, Reproducibility = 6, Exploitability = 7, Affected users = 9, Discoverability = 5. What is its DREAD risk score (simple average)?
Cevabı göster
DREAD puanı beş kategorinin ortalamasıdır..
0-10 ölçeğinde 7 yüksek sayılır, bu tehdit önceliklendirilir.
Threat T1 has likelihood 0.3 and impact 9. Threat T2 has likelihood 0.6 and impact 5. Using risk = likelihood × impact, which threat should be fixed first, and what are the two risk values?
Cevabı göster
, .
Etkisi daha küçük olsa da T2'nin olasılığı iki kat fazla, toplam risk daha büyük. Sadece etkiye bakıp T1'i seçmek tipik hatadır.
Which secure design principle does the code below violate?
boolean canDelete(User u, Doc d) {
try {
return acl.check(u, d, "DELETE");
} catch (Exception e) {
return true; // ACL service down, let it through
}
}- Least privilege
- Fail-safe defaults
- Open design
- Separation of privilege
Cevabı göster
Hata durumunda kod erişime izin veriyor. Güvenli varsayılan (fail-safe defaults) ilkesine göre varsayılan karar "reddet" olmalı, erişim sadece açıkça izin verildiğinde açılmalı. ACL servisi çökünce herkesin her belgeyi silebilmesi tam olarak bu ilkenin ihlali. Düzeltme: catch bloğunda return false; ve olayı logla.
An application checks a user's permissions only once at login and caches the result for the whole session. An admin revokes the user's access, but the user keeps working for hours. Which principle is violated?
- Economy of mechanism
- Complete mediation
- Psychological acceptability
- Open design
Cevabı göster
Tam aracılık (complete mediation): her nesneye her erişimde yetki yeniden denetlenmeli. Sonucu önbellekte tutup bir daha bakmamak, yetki geri alındığında bile erişimin sürmesine yol açar. Önbellek kullanılacaksa kısa ömürlü olmalı ve yetki değişince geçersiz kılınmalı.
In which SDLC phase is threat modeling most cost-effective to perform?
- Requirements and design
- Deployment
- Maintenance
- After a penetration test fails
Cevabı göster
Tehdit modelleme mimari ortaya çıkarken yapılır. Tasarım hatasını tasarım aşamasında düzeltmek bir çizim değişikliğidir. Aynı hata canlıya çıktıktan sonra bulunursa yeniden mimari, yama ve olay müdahalesi gerekir; maliyet katlanarak artar.
How does a misuse case differ from a normal use case?
- It describes a feature the customer forgot to request
- It describes how an attacker (misactor) could abuse the system, and drives security requirements
- It is a use case with no actors
- It is a test case written after deployment
Cevabı göster
Kullanım senaryosu (use case) sistemin ne yapması gerektiğini anlatır. Kötüye kullanım senaryosu (misuse/abuse case) kötü niyetli bir aktörün sistemi nasıl suistimal edebileceğini anlatır. Her misuse case bir karşı önleme, yani bir güvenlik gereksinimine (security requirement) dönüşür: örn. "brute-force parola denemesi" → "5 hatalı denemeden sonra hesap 15 dk kilitlenir".
Which STRIDE threat is mitigated mainly by authorization checks?
- Spoofing
- Information disclosure
- Denial of service
- Elevation of privilege
Cevabı göster
Yetki yükseltme (elevation of privilege): kullanıcının izinli olmadığı bir işi yapabilmesi. Karşılığı yetkilendirme (authorization). Spoofing'in karşılığı kimlik doğrulama, Information disclosure'ın gizlilik, DoS'un erişilebilirlik.
A system has three independent defense layers. An attacker bypasses them with probabilities 0.1, 0.2 and 0.05 respectively. Assuming independence, what is the probability that the attacker gets through all three layers?
Cevabı göster
Katmanlar bağımsız ve saldırganın hepsini aşması gerekiyor, olasılıklar çarpılır:.
En az bir katmanın tutma olasılığı . Derinlemesine savunmanın (defense in depth) gücü buradan gelir. Tuzak: katmanlar aynı zayıflığı paylaşıyorsa (örn. aynı parola) bağımsızlık varsayımı çöker.
Doğrulama: DREAD ortalamaları, risk = olasılık × etki çarpımları ve katmanlı savunma olasılıkları node ile hesaplandı (verify/SEN2008/13.mjs). Kavramsal cevaplar Saltzer-Schroeder (1975) ilkeleri ve Microsoft STRIDE tanımlarıyla karşılaştırıldı.