# Güvenlik Denetimi & Yayın Öncesi İyileştirme Planı

## [Overview]
Markamama Kariyer uygulamasının yayına alınmadan önce kapsamlı güvenlik denetimi ve kod kalitesi iyileştirmesi.

Bu plan; Laravel 11 + Fortify + Spatie Permission tabanlı kariyer yönetim sisteminin tüm katmanlarını (ortam yapılandırması, kimlik doğrulama, yetkilendirme, dosya yükleme, rate limiting, HTTP güvenlik başlıkları, CSP, oturum güvenliği, kayıt açığı, kod kalitesi) kapsamlı biçimde inceler ve her birini düzeltmek için somut adımlar sunar.

**Tespit edilen kritik sorunlar özeti:**
1. `.env` → `APP_DEBUG=true`, `APP_ENV=local`, `DB_PASSWORD=` boş — production'a geçişte felaket
2. Fortify `Features::registration()` açık — herkes admin hesabı oluşturabilir
3. `SESSION_SECURE_COOKIE` tanımsız (null) — HTTPS'de cookie çalınabilir
4. CSP'de `'unsafe-inline'` ve `'unsafe-eval'` var — XSS koruması zayıf
5. `composer.json` → `"block-insecure": false` — güvenlik açıklı paketler engellenmez
6. `storage/app/backups/` dizini web'den erişilebilir olabilir
7. Fortify `home` → `/home` route'u yok, login sonrası 404
8. `virustotal_api_key` SiteSetting'de düz metin saklanıyor (şifrelenmemiş)
9. `export applications` izni AdminUserSeeder'da tanımlanmamış
10. Rate limiting sadece başvuru formunda var; admin login brute-force koruması Fortify'a bırakılmış ama özelleştirilmemiş
11. `public/storage` symlink yoksa CV'ler erişilemez (avatar için)
12. `RECAPTCHA_SITE_KEY` boş — bot koruması devre dışı

---

## [Güvenlik Açıkları — Kritiklik Sırası]

### 🔴 KRİTİK

**1. Açık Kayıt (Public Registration)**
- Dosya: `config/fortify.php` satır 165
- Sorun: `Features::registration()` aktif → herkes `/register` ile admin paneline girebilecek kullanıcı oluşturabilir
- Düzeltme: `Features::registration()` satırını kaldır veya yorum satırına al. Kullanıcı oluşturma sadece admin panelinden yapılmalı.

**2. APP_DEBUG=true Production'da**
- Dosya: `.env`
- Sorun: Hata mesajları, stack trace, DB sorguları, env değerleri tarayıcıda görünür
- Düzeltme: Production `.env`'de `APP_DEBUG=false`, `APP_ENV=production` olmalı

**3. Boş Veritabanı Şifresi**
- Dosya: `.env` satır 28
- Sorun: `DB_PASSWORD=` boş — production sunucuda mutlaka güçlü şifre olmalı
- Düzeltme: Güçlü rastgele şifre set et

**4. SESSION_SECURE_COOKIE Tanımsız**
- Dosya: `.env` (SESSION_SECURE_COOKIE yok), `config/session.php` satır 172
- Sorun: `env('SESSION_SECURE_COOKIE')` → null döner → HTTPS'de bile cookie `Secure` flag'i taşımaz → session hijacking riski
- Düzeltme: `.env`'e `SESSION_SECURE_COOKIE=true` ekle (production için)

**5. Fortify Home Route Yok**
- Dosya: `config/fortify.php` satır 76
- Sorun: `'home' => '/home'` ama bu route tanımlı değil → login sonrası 404
- Düzeltme: `'home' => '/admin/dashboard'` olarak değiştir

### 🟠 YÜKSEK

**6. CSP'de unsafe-inline ve unsafe-eval**
- Dosya: `app/Http/Middleware/SecurityHeaders.php` satır 24
- Sorun: `'unsafe-inline'` ve `'unsafe-eval'` XSS saldırılarına kapı açar
- Düzeltme: Nonce tabanlı CSP'ye geçiş veya en azından `'unsafe-eval'` kaldırılmalı

**7. composer.json audit block-insecure=false**
- Dosya: `composer.json` satır 74 ve 81
- Sorun: Bilinen güvenlik açıklı paketler yüklemeyi engellemez
- Düzeltme: `"block-insecure": true` yap, `composer audit` çalıştır

**8. VirusTotal API Key Düz Metin**
- Dosya: `app/Models/SiteSetting.php` — `virustotal_api_key` şifrelenmeden DB'ye yazılıyor
- Sorun: DB dump alındığında API key açık görünür
- Düzeltme: `SiteSetting::set()` içinde hassas key'ler için `encrypt()`/`decrypt()` kullan

**9. export/merge-excel İzni Seeder'da Eksik**
- Dosya: `database/seeders/AdminUserSeeder.php`
- Sorun: `'export applications'` izni tanımlanmamış ama route'da kullanılıyor → 403 hatası
- Düzeltme: Seeder'a `'export applications'` ve `'manage site settings'`, `'view site settings'`, `'view logs'` izinlerini ekle

**10. Backup Dosyaları Web'den Erişilebilir Olabilir**
- Dosya: `app/Http/Controllers/Admin/SiteSettingController.php` satır 90
- Sorun: `storage_path('app/backups')` → `storage/app/backups/` → eğer `public/storage` symlink varsa ve yanlış yapılandırılmışsa erişilebilir
- Düzeltme: Backup dizinini `storage/app/private/backups/` altına taşı, `.htaccess` ile koru

**11. Fortify Login Rate Limit Yetersiz**
- Dosya: `app/Providers/FortifyServiceProvider.php` satır 40
- Sorun: 5 deneme/dakika — brute force için yeterli değil, lockout yok
- Düzeltme: `Limit::perMinute(5)->by(...)->response(...)` ile 429 + lockout süresi ekle; veya `perMinutes(15, 5)` kullan

**12. RECAPTCHA Boş**
- Dosya: `.env` satır 67-68
- Sorun: `RECAPTCHA_SITE_KEY=` boş → başvuru formunda bot koruması yok
- Düzeltme: Google reCAPTCHA v3 key'lerini ekle ve `StoreApplicationRequest`'e doğrulama ekle

### 🟡 ORTA

**13. Session SameSite=lax (strict olmalı)**
- Dosya: `config/session.php` satır 202
- Sorun: `lax` CSRF saldırılarına karşı `strict`'ten daha az koruma sağlar
- Düzeltme: `SESSION_SAME_SITE=strict` (admin-only uygulama için uygundur)

**14. X-XSS-Protection Header Eski**
- Dosya: `app/Http/Middleware/SecurityHeaders.php` satır 17
- Sorun: `X-XSS-Protection: 1; mode=block` modern tarayıcılarda deprecated, bazılarında güvenlik açığı oluşturur
- Düzeltme: `X-XSS-Protection: 0` yap (CSP bunu zaten karşılar)

**15. Fortify Kayıt Sonrası E-posta Doğrulama Kapalı**
- Dosya: `config/fortify.php` satır 167
- Sorun: `Features::emailVerification()` yorum satırında → kayıt olan kullanıcı doğrulanmadan giriş yapabilir
- Düzeltme: Kayıt kapatıldıktan sonra bu zaten sorun olmaz; ama admin kullanıcı oluşturma akışında `email_verified_at` set edilmeli (seeder'da zaten var)

**16. Avatar Dosyaları public disk'te**
- Dosya: `app/Http/Controllers/Admin/ProfileController.php` satır 71
- Sorun: Avatar `public` disk'e kaydediliyor → URL tahmin edilebilir, doğrudan erişilebilir
- Düzeltme: Kabul edilebilir (avatar public olabilir), ama dosya adı UUID olmalı (şu an Laravel'in varsayılan hash'i kullanılıyor — bu iyi)

**17. Maintenance Mode Secret Tahmin Edilebilir**
- Dosya: `app/Http/Controllers/Admin/SiteSettingController.php` satır 315
- Sorun: `'markamama-bypass-' . substr(md5(config('app.key')), 0, 8)` — APP_KEY bilinirse bypass URL tahmin edilebilir
- Düzeltme: `Str::random(32)` ile tamamen rastgele secret üret ve DB'ye kaydet

**18. Log Level=debug Production'da**
- Dosya: `.env` satır 21
- Sorun: `LOG_LEVEL=debug` → hassas veriler log'a yazılabilir
- Düzeltme: Production'da `LOG_LEVEL=error` veya `warning`

**19. CV Dosyası Orijinal Adı Saklanıyor**
- Dosya: `app/Http/Controllers/Public/JobController.php` satır 56
- Sorun: `$file->getClientOriginalName()` → kullanıcı kontrolündeki veri DB'ye yazılıyor; XSS için kullanılabilir (view'da escape edilmeli)
- Düzeltme: View'larda `{{ $application->cv_original_name }}` kullanımını kontrol et (Blade zaten escape eder — OK), ama download header'ında `Content-Disposition` için sanitize et

**20. Bulk Status Route Sırası**
- Dosya: `routes/web.php` satır 85
- Sorun: `Route::post('basvurular/bulk-status', ...)` — `{application}` parametreli route'lardan SONRA tanımlanmış ama `basvurular/bulk-status` string'i model binding'e takılabilir
- Düzeltme: `bulk-status` route'unu `{application}` içeren route'lardan ÖNCE tanımla (zaten öyle görünüyor ama doğrula)

### 🟢 DÜŞÜK / İYİLEŞTİRME

**21. DB_PASSWORD Boş — Root Kullanıcısı**
- Production'da root yerine ayrı bir DB kullanıcısı oluştur, sadece ilgili DB'ye erişim ver

**22. MAIL_MAILER=log**
- Production'da gerçek SMTP (Mailgun, SES, vb.) yapılandırılmalı

**23. QUEUE_CONNECTION=database**
- Production'da Redis önerilir; database queue yüksek trafikte yavaşlar

**24. Fortify home=/home**
- Login sonrası yönlendirme `/admin/dashboard` olmalı

**25. AppServiceProvider Boş**
- Model::preventLazyLoading(), Model::shouldBeStrict() eklenebilir (N+1 önleme)

**26. composer audit Çalıştırılmamış**
- Bilinen CVE'lere karşı paket denetimi yapılmalı

---

## [Files]
Değiştirilecek dosyalar listesi.

### Değiştirilecek Dosyalar:
- `.env` → APP_DEBUG, APP_ENV, SESSION_SECURE_COOKIE, LOG_LEVEL, SESSION_SAME_SITE düzeltmeleri
- `.env.example` → Güvenli production template
- `config/fortify.php` → registration kaldır, home düzelt
- `config/session.php` → same_site default strict
- `app/Http/Middleware/SecurityHeaders.php` → CSP nonce, X-XSS-Protection=0
- `app/Providers/FortifyServiceProvider.php` → Rate limit iyileştirme
- `app/Providers/AppServiceProvider.php` → Model strict mode, URL::forceScheme
- `app/Http/Controllers/Admin/SiteSettingController.php` → Backup dizini, maintenance secret
- `database/seeders/AdminUserSeeder.php` → Eksik izinler ekleme
- `composer.json` → block-insecure: true
- `routes/web.php` → Route sırası doğrulama

### Yeni Oluşturulacak Dosyalar:
- `app/Http/Middleware/ForceHttps.php` → Production'da HTTPS zorunlu kılma middleware
- `public/.htaccess` → Güvenlik başlıkları (Apache için)

---

## [Functions]

### Değiştirilecek Fonksiyonlar:
- `FortifyServiceProvider::boot()` → Rate limit perMinutes(15, 5) + lockout response
- `SiteSettingController::maintenanceToggle()` → Rastgele secret
- `AppServiceProvider::boot()` → Model::preventLazyLoading() ekle
- `SecurityHeaders::handle()` → X-XSS-Protection=0, CSP nonce

### Yeni Fonksiyonlar:
- `AppServiceProvider::boot()` → URL::forceScheme('https') production'da
- `ForceHttps::handle()` → HTTPS yönlendirme middleware

---

## [Classes]

### Değiştirilecek Sınıflar:
- `SecurityHeaders` → CSP güçlendirme
- `FortifyServiceProvider` → Rate limiting iyileştirme
- `AppServiceProvider` → Strict mode, HTTPS forcing
- `AdminUserSeeder` → Eksik izinler

---

## [Dependencies]

### Önerilen Eklemeler:
- `composer require pragmarx/google2fa-laravel` → 2FA zaten Fortify ile var, ek paket gerekmez
- `composer audit` → Mevcut paketlerde CVE kontrolü
- `"block-insecure": true` → composer.json'da

---

## [Testing]

### Doğrulama Adımları:
1. `php artisan route:list` → Tüm route'ların doğru middleware'e sahip olduğunu kontrol et
2. `php artisan config:clear && php artisan cache:clear` → Config cache temizle
3. `/register` URL'sine git → 404 veya redirect olmalı (kayıt kapalı)
4. Login sayfasında 5+ başarısız deneme → 429 Too Many Requests alınmalı
5. `composer audit` → Güvenlik açıklı paket olmamalı
6. Browser DevTools → Response headers'da CSP, HSTS, X-Frame-Options kontrol et
7. `APP_DEBUG=false` ile hata sayfasının stack trace göstermediğini doğrula

---

## [Implementation Order]
Uygulama sırası — kritikten düşüğe doğru.

1. **[KRİTİK] Fortify registration'ı kapat** → `config/fortify.php`
2. **[KRİTİK] Fortify home route'unu düzelt** → `config/fortify.php`
3. **[KRİTİK] .env production değerlerini düzelt** → APP_DEBUG=false, SESSION_SECURE_COOKIE=true, LOG_LEVEL=error
4. **[KRİTİK] Eksik izinleri seeder'a ekle** → AdminUserSeeder.php
5. **[YÜKSEK] composer.json block-insecure=true + composer audit**
6. **[YÜKSEK] Rate limiting iyileştir** → FortifyServiceProvider
7. **[YÜKSEK] Session same_site=strict** → .env / config/session.php
8. **[YÜKSEK] Maintenance secret rastgele** → SiteSettingController
9. **[ORTA] SecurityHeaders CSP güçlendirme** → X-XSS-Protection=0
10. **[ORTA] AppServiceProvider** → Model strict mode, URL::forceScheme
11. **[DÜŞÜK] .env.example güncelle** → Production template
12. **[DÜŞÜK] composer audit çalıştır ve rapor al**