first commit
This commit is contained in:
125
guvenlik-raporu.md
Normal file
125
guvenlik-raporu.md
Normal file
@@ -0,0 +1,125 @@
|
||||
## Go Backend API Güvenlik Raporu
|
||||
|
||||
### 1. Genel Değerlendirme
|
||||
|
||||
- **Kapsam**: Kod tabanı üzerinden statik güvenlik analizi ve `go vet ./...` ile temel statik araç kontrolü.
|
||||
- **Genel Sonuç**: Mimari olarak sağlam bir temel var (JWT, rol tabanlı yetki, rate limit, CORS). En önemli eksik, **refresh token güvenliğinin state-less olması (rotation/revoke yok)** ve **API tarafında token invalidation / logout akışının olmaması**.
|
||||
|
||||
### 2. Güçlü Yönler
|
||||
|
||||
- **JWT ve Kimlik Doğrulama**
|
||||
- HS256 ile imzalama yapılıyor ve `SigningMethodHMAC` kontrolü var → `alg: none` benzeri saldırılara karşı temel koruma mevcut.
|
||||
- Access / refresh token ayrımı `TokenType` alanı ile net; `RequireAuth` yalnızca access token kabul ediyor.
|
||||
- Email doğrulaması yapılmadan login’e izin verilmiyor.
|
||||
|
||||
- **Rol ve Yetkilendirme**
|
||||
- Public API tarafında admin işlemleri `RequireAuth` + `RequireAdmin` middleware’leri ile korunuyor.
|
||||
- Admin panel altındaki `"/admin"` rotaları global olarak `RequireAuth` + `RequireAdmin` ile kapalı.
|
||||
|
||||
- **CORS**
|
||||
- DB + Redis destekli whitelist/blacklist ile **default deny** yaklaşımı kullanılıyor.
|
||||
- Same-origin istekler her zaman izinli, wildcard `*` yok → klasik açık CORS yanlış konfigürasyonları görülmedi.
|
||||
|
||||
- **Rate Limiting**
|
||||
- `/api/v1` için global; `/auth/login` ve `/auth/refresh` için isimlendirilmiş rate limit profilleri tanımlı.
|
||||
- Redis tabanlı sayaçlar ile limit aşıldığında `429` ve `Retry-After` header’ı dönüyor.
|
||||
|
||||
- **Admin Oturumu (Browser)**
|
||||
- `admin_session` cookie: `HttpOnly`, `Secure`, `SameSite=Strict` → XSS sonrası cookie çalınması ve CSRF riskleri azaltılmış.
|
||||
- Admin login’de parolalar `bcrypt` ile doğrulanıyor.
|
||||
|
||||
### 3. Tespit Edilen Riskler ve Öneriler
|
||||
|
||||
#### 3.1 Refresh Token Rotation & Revoke Eksikliği (Kritik / Yüksek Öncelik)
|
||||
|
||||
- **Durum**:
|
||||
- `/api/v1/auth/refresh` endpoint’i yalnızca:
|
||||
- JWT imzasını,
|
||||
- `TokenType == refresh` olmasını
|
||||
kontrol ediyor.
|
||||
- Refresh token’lar için DB/Redis tabanlı bir “token store”, revoke listesi veya rotation takibi yok.
|
||||
- **Risk**:
|
||||
- Bir refresh token ele geçirilirse, süresi dolana kadar sınırsız sayıda yeni access token üretmek için yeniden kullanılabilir.
|
||||
- Token reuse (aynı refresh token’ın birden fazla kez kullanılması) tespit edilemiyor.
|
||||
- **Öneri**:
|
||||
- Refresh token’lar için tablo veya Redis store tasarla:
|
||||
- Her refresh isteğinde:
|
||||
- Eski refresh token’ı **geçersiz** kıl (rotation),
|
||||
- Yeni bir refresh token üret ve store’a kaydet.
|
||||
- Aynı refresh token ikinci kez kullanılırsa:
|
||||
- İlgili hesabı veya oturumu geçici olarak kilitle,
|
||||
- Gerekirse tüm tokenlarını revoke et (global logout).
|
||||
- Mümkünse refresh token’ları **HTTP-only cookie** ile taşı (XSS’e karşı daha dirençli).
|
||||
|
||||
#### 3.2 API Logout / Token İptali Eksikliği (Orta–Yüksek)
|
||||
|
||||
- **Durum**:
|
||||
- Public API’de `/api/v1/auth/logout` benzeri bir endpoint yok.
|
||||
- Client tarafında yalnızca local storage / memory’den token silinerek logout yapılıyor; backend tarafında “session state” yok.
|
||||
- **Risk**:
|
||||
- Bir access veya refresh token sızdığında, expire olana kadar backend tarafında bunu geçersiz kılma imkânı yok.
|
||||
- Özellikle refresh token için kritik: saldırgan elinde refresh token olduğu sürece yeni access token üretebilir.
|
||||
- **Öneri**:
|
||||
- `/api/v1/auth/logout` endpoint’i ekle:
|
||||
- İlgili kullanıcının aktif refresh token kaydını (veya kayıtlardan birini) revoke listesine ekle ya da store’dan sil.
|
||||
- İsteğe bağlı olarak access token için kısa süreli bir blacklist kullan (jti/subject bazlı).
|
||||
- Admin panel logout şu an cookie temizliyor; bunu backend tarafında da bir “session invalidation” akışı ile desteklemek düşünülebilir.
|
||||
|
||||
#### 3.3 Token İçeriğinin Loglanması (Düşük–Orta)
|
||||
|
||||
- **Durum**:
|
||||
- `GenerateTokenPair` içinde development ortamında hem access hem refresh token string’leri loglanıyor.
|
||||
- Refresh akışında `fmt.Println(accessToken, "Access Token Yenilendi !!!")` ile access token stdout’a yazılıyor.
|
||||
- **Risk**:
|
||||
- Production konfigürasyonu yanlış yapılırsa, log dosyalarında tam token değerleri yer alabilir.
|
||||
- **Öneri**:
|
||||
- Production ortamında:
|
||||
- Token gövdesini **asla** loglama; yalnızca `userID`, `exp`, `tokenType` gibi meta verileri logla.
|
||||
- Development ortamında bile mümkünse:
|
||||
- Token’ı maskeleyerek veya kısmi göstererek logla (örneğin sadece ilk 6 + son 4 karakter).
|
||||
|
||||
#### 3.4 Admin Login – Captcha / Turnstile Doğrulaması Tamamlanmamış (Orta)
|
||||
|
||||
- **Durum**:
|
||||
- Admin login formu `cf-turnstile-response` alanını okuyor ancak gerçek Cloudflare Turnstile doğrulaması yapılmıyor.
|
||||
- Rate limiting mevcut olsa da insan/makine ayrımı yok.
|
||||
- **Risk**:
|
||||
- Admin hesabı için brute force ve credential stuffing saldırılarına karşı savunma zayıf kalıyor.
|
||||
- **Öneri**:
|
||||
- Cloudflare Turnstile veya benzeri servis için gerçek HTTP doğrulamasını ekle:
|
||||
- Turnstile token’ı backend’de doğrulanmadan login’e izin verme.
|
||||
- Başarısız giriş denemelerine göre:
|
||||
- IP ve hesap bazlı ek limitler veya geçici hesap kilitleme mekanizması eklemeyi değerlendir.
|
||||
|
||||
#### 3.5 Redis Yoksa Rate Limit & CORS Enforcement’ın Devre Dışı Kalması (Düşük–Orta)
|
||||
|
||||
- **Durum**:
|
||||
- Redis bağlantısı yoksa, rate limit ve CORS cache tarafı graceful fail yapıyor ve bazı kontroller uygulanmayabiliyor.
|
||||
- **Risk**:
|
||||
- Production’da Redis yanlış konfigüre edilirse, rate limit fiilen devre dışı kalabilir; CORS kontrolleri de zayıflayabilir.
|
||||
- **Öneri**:
|
||||
- Production ortamında Redis’i **zorunlu bağımlılık** haline getir:
|
||||
- Redis’e bağlanılamıyorsa servisi başlatma (fail-fast).
|
||||
- Redis bağlantı hatalarını loglarda daha yüksek seviye (error) olarak işaretle.
|
||||
|
||||
### 4. `go vet` Çıktısı Özeti
|
||||
|
||||
- `go vet ./...` komutu çalıştırıldığında:
|
||||
- `scripts/seed.go` içinde aynı pakette birden fazla `main` fonksiyonu olduğu için “main redeclared” uyarısı veriliyor.
|
||||
- **Not**:
|
||||
- Bu, güvenlikten ziyade script yapısına dair yapısal bir uyarı; istenirse ilgili script ayrı bir pakete veya dosya yapısına taşınarak temizlenebilir.
|
||||
|
||||
### 5. Önerilen İyileştirme Planı (Önceliklendirilmiş)
|
||||
|
||||
1. **Kritik (kısa vadede)**:
|
||||
- Refresh token için rotation + revoke mekanizması tasarlayıp uygulamak.
|
||||
- Public API için `/api/v1/auth/logout` endpoint’i ekleyip refresh (ve gerekiyorsa access) token’larını server-side olarak da geçersiz kılmak.
|
||||
- Production’da token içeriğini loglamayı tamamen kapatmak; development’ta da maskelemek.
|
||||
|
||||
2. **Orta vadede**:
|
||||
- Admin login için gerçek Turnstile (veya eşdeğer captcha) doğrulamasını devreye almak.
|
||||
- Redis’i production ortamında zorunlu hale getirip rate limit/CORS’un Redis olmadan çalışmamasını sağlamak (fail-fast yaklaşımı).
|
||||
|
||||
3. **Uzun vadede**:
|
||||
- Bu rapora göre hazırlanmış, dış pentest’e verilebilecek detaylı bir test senaryoları dokümanı oluşturmak (mevcut `guvenlik.md` şablonunu projeye özgü endpoint/roller ile doldurmak).
|
||||
|
||||
Reference in New Issue
Block a user