Güvenlik

Yayın öncesi güvenlik kapısı: her sürüm nasıl denetleniyor

Kendi geliştirdiğim security-gate aracının kontrolleri ve karar mantığı; sunucu ve e-posta tarafında sahada öğrendiğim, kimsenin önceden söylemediği dersler.

· 5 dk okuma

Güvenlik açıkları çoğunlukla “yayına alırız, sonra bakarız” diye geçilen adımlarda doğar. Bu yüzden web siteleri ve mobil uygulamalar için yayını bir kapıya bağladım: kapıdan geçemeyen sürüm yayına çıkmıyor. Bu kapıyı kendim geliştirdim ve adı security-gate. Bu yazıda neyi, nasıl kontrol ettiğini ve sahada öğrendiğim dersleri anlatıyorum.

Kapı neleri kontrol ediyor

Alan Araç ya da yöntem
Sızmış sırlar gitleaks ve trufflehog; hem çalışma dosyaları hem git geçmişinin tamamı
Statik kod analizi semgrep, OWASP ve CWE kural setleri
Bağımlılıklar ve imajlar trivy ve yazılım malzeme listesi (SBOM)
Açık yüzey taraması nuclei, 900’ü aşkın topluluk şablonu
TLS yapılandırması testssl
Dinamik test (DAST) OWASP ZAP
HTTP güvenlik başlıkları Araca gömülü kontrol
DNS ve e-posta hijyeni DMARC, CAA, MTA-STS, TLS-RPT ve DKIM kontrolü
Altyapı Port taraması, SSH denetimi, imaj ve sunucu sertleştirme

Kontroller projeye göre açılıp kapatılabiliyor. Statik bir sitede SSH denetimi anlamsızken, bir API sunucusunda şart.

Karar mantığı

Her kontrol dört sonuçtan birini döndürüyor: geçti, kaldı, insan incelemesi gerekli ya da uygulanamaz. Bulgular OWASP Top 10:2025, ASVS 5.0 ve CWE Top 25 ile eşleniyor; raporda her bulgunun hangi standarda karşılık geldiği görünüyor.

Yayın iki durumda otomatik olarak durduruluyor:

  1. Doğrulanmış ve hâlâ geçerli bir sır bulunduysa. Bir anahtarın yalnızca dosyada görünmesi değil, gerçekten çalıştığının doğrulanması önemli.
  2. Zorunlu insan incelemesi maddeleri kapatılmadıysa.

Neden bazı maddeler insana bırakılıyor

Kimlik doğrulama ve oturum yönetimi, erişim kontrolü, iş mantığı, tehdit modeli ve dış sızma testi otomatik araçlarla güvenilir biçimde onaylanamaz. Bir tarayıcı, “müşteri A, müşteri B’nin faturasını görebiliyor mu” sorusunu cevaplayamaz. Bu maddeler, bir insan kontrol edip kapatmadan yayın açılmıyor.

Çıktılar

Rapor JSON, Markdown ve SARIF biçiminde üretiliyor; SARIF, bulguların doğrudan kod barındırma platformunun güvenlik sekmesinde görünmesini sağlıyor. Ayrıca CycloneDX biçiminde bir yazılım malzeme listesi ve her adımı sırasıyla kaydeden bir olay günlüğü çıkıyor.

Güvenlik aracının kendisi nasıl test ediliyor

Bir güvenlik aracı, yanlışlıkla “geçti” dediği gün en tehlikeli hâline gelir. Bu yüzden aracın kendi test kapsamını ciddiye alıyorum: son sürümde 464 test, 13 Docker entegrasyon testi ve yaklaşık %90 satır kapsamı var; testler her değişiklikte sürekli entegrasyonda çalışıyor.

Bu testler sayesinde yakaladığım iki gerçek sorun:

Web ve mobil için standart kontrollerim

Sunucu tarafında öğrendiğim dersler

Birden fazla sunucuyu tek bir hedef sunucuda birleştirirken ve kendi e-posta sunucumu işletirken karşılaştığım, dokümanlarda kolay bulunmayan durumlar:

Docker, güvenlik duvarını atlar

Docker’ın dışarıya açtığı konteyner portları, ufw kurallarının bulunduğu zincirden değil, Docker’ın kendi yönlendirme kurallarından geçer. Yani ufw ile kapattığınızı düşündüğünüz port açık kalabilir. Filtre DOCKER-USER zincirine yazılmalı. Üstelik Docker paketi hedef porta çevirdikten sonra eşleşme yapıldığı için kural, özgün porta -m conntrack --ctorigdstport ile bakmalı; aksi hâlde port sessizce açık kalır.

Tek dosya bağlamaları ve yerinde düzenleme

Konteynere tek bir dosya olarak bağlanmış bir yapılandırmayı sed -i ile düzenlemek yeni bir dosya oluşturur. Konteyner eski dosyayı görmeye devam eder: komut başarılı görünür ama değişiklik uygulanmaz. Bu yüzden bir değişikliği her zaman canlı yanıttan doğruluyorum, komutun çıktısından değil.

Yeniden oluşturulan konteyner ağ bağlantısını kaybeder

Elle bir ağa bağlanmış ters vekil konteyneri docker compose up -d ile yeniden oluşturulduğunda o bağlantı düşer ve arkasındaki bütün siteler 502 verir. Kalıcı çözüm, paylaşılan ağı compose dosyasında harici ağ olarak tanımlamak.

Geri yüklenmemiş yedek, yedek değildir

Resmi bir yedekleme aracının ürettiği paketlerin, boş kalmış tek bir ayar yüzünden geri yüklenemediğini ancak geri yüklemeyi denediğimde gördüm. O günden beri her yedek, geri yüklenip doğrulanmadan “var” sayılmıyor. Her gece arşiv bütünlüğü test ediliyor ve dosya sayıları canlı sistemle karşılaştırılıyor.

Taşımada sessiz veri kaybı

E-posta sunucusunun tuzakları

İlkelerim

  1. Gerçek bir sır, özel bir depoda bile olsa hiçbir dosyaya, commit’e ya da sohbet kaydına yazılmaz.
  2. Bir kişinin girmesi gereken sır, kendi terminaline gizli girişle yazılır. Otomasyon değeri görmez, yalnızca özetini doğrular.
  3. Canlı bir sistemde değişiklikten önce her zaman bir geri dönüş noktası bırakılır.
  4. Yedekler sahibi açıkça istemedikçe otomatik silinmez.
  5. Yönetim arayüzleri ağa kapatılır ve yalnızca tünel üzerinden erişilir.
  6. Bir değişiklik, canlıda doğrulanmadan bitmiş sayılmaz.

Bu kapının kontrol ettiği sitelerin nasıl kurulduğunu web sitesi yazısında anlattım.