OWASP Top 10 (2021)

Web uygulamalarında en kritik 10 güvenlik riski. Her yeni proje bu maddeleri doğrulamadan üretime çıkmamalıdır.
Kritik

A01: Bozuk Erişim Kontrolü (Broken Access Control)

Neden önemli

Kullanıcılar yetkileri dışındaki kaynaklara erişebilir veya başka kullanıcıların verilerini değiştirebilir. 2021'de en sık karşılaşılan güvenlik açığıdır.

Nasıl uygula

Tüm endpoint'lerde sunucu tarafı yetki kontrolü zorunlu kıl. Default-deny politikası uygula. ID'leri tahmin edilemez yap (UUID/GUID). IDOR'a karşı her resource için 'sahibi mi?' kontrolü ekle. Tarayıcıdaki rol kontrolüne asla güvenme.

Örnek
Yanlış: GET /api/orders/123 — sadece login kontrol ediliyor. Doğru: order.UserId == currentUser.Id veya rol bazlı policy doğrulanıyor.
Kritik

A02: Kriptografik Hatalar (Cryptographic Failures)

Neden önemli

Hassas verilerin (parola, kart, kişisel veri) zayıf veya yanlış şifrelenmesi sızıntı durumunda doğrudan açığa çıkmasına yol açar.

Nasıl uygula

Parolaları bcrypt/argon2/scrypt ile hash'le (asla MD5/SHA1). Her yerde TLS 1.2+ kullan. Hassas alanları uygulama düzeyinde de şifrele. Eski/zayıf algoritmaları (DES, RC4, MD5) yasakla. Anahtarları KMS/Vault'ta tut.

Örnek
ASP.NET Core: PasswordHasher zaten PBKDF2 kullanır; daha güçlüsü için Argon2id (Konscious.Security.Cryptography.Argon2 paketi) önerilir.
Kritik

A03: Injection (SQL, NoSQL, OS, LDAP)

Neden önemli

Kullanıcı girdisi sorguya doğrudan eklenirse saldırgan veritabanı, dosya sistemi veya komut satırı üzerinden istediği kodu çalıştırabilir.

Nasıl uygula

Her zaman parametreli sorgu/prepared statement kullan. ORM'lerde raw SQL'den kaçın. Şablon motorlarında (HTML, e-posta) auto-escape açık olsun. Komut çağrılarında shell yerine argv listesi geç. Girdi doğrula, çıktı kodla.

Örnek
EF Core: db.Users.Where(u => u.Email == email) güvenli; FromSqlRaw($"... WHERE email = '{email}'") tehlikeli. Bunun yerine FromSqlInterpolated kullan.
Yüksek

A04: Güvensiz Tasarım (Insecure Design)

Neden önemli

Güvenlik koda eklenmez, tasarımda başlar. Threat modeling yapılmamış sistemlerde her özellik yeni saldırı yüzeyi açar.

Nasıl uygula

Her yeni özellik için STRIDE/abuse-case analizi yap. Veri sınıflandırması (public/internal/confidential) tanımla. Güvenli varsayılanlar: deny by default, secure by default. Rate limiting ve quota'ları tasarım aşamasında planla.

Örnek
Şifre sıfırlama tasarlanırken sadece 'token gönder' değil — token TTL'i, tek kullanımlık olması, IP/oran sınırı, eski oturumların geçersizleşmesi planlanmalı.
Yüksek

A05: Güvenlik Yanlış Yapılandırması (Security Misconfiguration)

Neden önemli

Default parolalar, açık dizin listeleme, gereksiz HTTP metodları, ayrıntılı hata mesajları — saldırganın işini kolaylaştırır.

Nasıl uygula

Production'da DETAILED_ERRORS kapalı. Default credentials değiştir/sil. Kullanılmayan portları/feature'ları kapat. Security headers ekle: HSTS, X-Content-Type-Options, X-Frame-Options/CSP, Referrer-Policy. CORS dar tanımla.

Örnek
ASP.NET Core: app.UseHsts(), app.UseHttpsRedirection(); response header'larına Content-Security-Policy ekle; UseDeveloperExceptionPage sadece Development'ta.
Yüksek

A06: Bilinen Açıklı/Eski Bileşenler (Vulnerable & Outdated Components)

Neden önemli

Bilinen CVE'si olan paketler kullanılırsa saldırganın hazır exploit'i vardır. Modern uygulamalar yüzlerce transitive bağımlılık taşır.

Nasıl uygula

Dependency scanning otomasyonu (Dependabot, Renovate, npm audit, dotnet list package --vulnerable). SBOM üret. Güncellemeleri küçük ve sık yap; major upgrade'leri planla. Kullanılmayan bağımlılıkları temizle.

Örnek
GitHub Actions ile dotnet list package --vulnerable --include-transitive komutunu CI'da çalıştır; bulgular > 0 ise build fail.
Kritik

A07: Kimlik Doğrulama ve Oturum Hataları

Neden önemli

Zayıf parola politikası, MFA eksikliği, brute-force koruması yokluğu, session ID'lerin yanlış yönetimi hesap ele geçirmeye yol açar.

Nasıl uygula

MFA'yı varsayılan ya da en az opsiyonel sun. Parola minimum 8+ karakter, common-password listesine karşı kontrol et. Login/register/forgot endpoint'lerine rate limiting koy. Session ID'leri httpOnly+Secure+SameSite=Lax cookie'de tut. Logout'ta session'ı sunucuda invalidate et.

Örnek
ASP.NET Core Identity'de Lockout aktif (5 başarısız → 15 dk kilit), TwoFactorEnabled kullanıcıya sun, RequireUniqueEmail = true.
Yüksek

A08: Yazılım ve Veri Bütünlüğü Hataları

Neden önemli

Doğrulanmamış kaynaktan kütüphane çekmek, imzasız update mekanizması, CI/CD pipeline'ında zayıf izolasyon — supply chain saldırılarını kolaylaştırır.

Nasıl uygula

Bağımlılıkları lock dosyası ile sabitle (package-lock.json, packages.lock.json). NuGet için signed package zorunlu kıl. CI sırlarını GitHub OIDC/Azure Federated Identity ile geçici tut. Imza doğrulamayan webhook'ları reddet.

Örnek
.csproj'da <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> ve <RestoreLockedMode>true</RestoreLockedMode>; pipeline yetkileri least-privilege.
Yüksek

A09: Güvenlik Loglama ve İzleme Eksikleri

Neden önemli

Saldırının ortalama tespit süresi aylar mertebesinde. Log yoksa veya alarm kurulmamışsa olay yaşandığını bile anlayamazsın.

Nasıl uygula

Login başarı/başarısızlığı, yetki reddi, kritik veri değişimi, admin eylemleri için yapılandırılmış log üret. Hassas veriyi log'a yazma. Logları merkezi sistemde (ELK, Seq, Datadog, CloudWatch) topla. Anormal aktivite için alert tanımla.

Örnek
Serilog + Seq: login fail için Warning seviyesinde log; aynı IP'den 1 dakikada 10+ failed login → Slack/email alarm.
Yüksek

A10: Sunucu Tarafı İstek Sahteciliği (SSRF)

Neden önemli

Sunucu, kullanıcının verdiği URL'e istek atıyorsa saldırgan iç ağ servisleri, cloud metadata endpoint'leri (169.254.169.254) veya admin panel'lere erişebilir.

Nasıl uygula

Kullanıcı URL'lerini whitelist domain'lere kısıtla. DNS rebinding'e karşı IP'yi resolve et ve private/loopback aralıklarını reddet. HTTP istemcisinde redirect takibini kapat veya kontrollü yap. Proxy/firewall ile çıkış trafiğini sınırla.

Örnek
Webhook delivery / link preview gibi özellikler tipik SSRF kaynağıdır; URL'i fetch etmeden önce IPAddress.Parse ile IsPrivate/IsLoopback kontrolü yap.