Site açılıyor, sayfa yükleniyor, ama tarayıcı konsolu kırmızı hatalarla dolu ve çalışması gereken düğme çalışmıyor. Ya da daha kötüsü: masaüstünde her şey doğru ve mobilde sayfanın bir kısmı beyaz kalıyor. Bu belirtiyi gördüğüm on vakadan dokuzunda, biri bir güvenlik başlığını katı bir değerle etkinleştirmiş ve sonra o başlığın kendi alan adını da kısıtladığını unutmuş. Güvenlik başlığı iyi bir araçtır, ama ABS freni gibidir: nereye basacağını bilmezsen, kendisi kazaya neden olur.
Her şeyden önce, şu anda sunucuda neyin ayarlandığını görelim. Basit bir komut yeterli:
curl -sI https://example.com | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'
Çıktı boşsa, hiçbir güvenlik başlığınız yok demektir. Doluysa, önce her birinin tam olarak ne yaptığını anlamalısınız, çünkü etkinleştirme sırası etkinleştirmenin kendisinden daha önemlidir.
Her güvenlik başlığı hangi saldırıyı kapatır
Başlıklar iki gruba ayrılabilir: tarayıcıyı durduranlar ve saldırganı durduranlar. Birinci grup hızlı etki eder ve riski düşüktür. İkinci grubun etkisi daha derindir ama yanlış ayarlanırsa siteyi kullanıcı erişiminden çıkarır.
| Başlık | Kapattığı saldırı | Hata riski |
|---|---|---|
X-Content-Type-Options: nosniff | MIME sniffing ve yüklenen dosyanın script olarak çalıştırılması | Neredeyse sıfır |
X-Frame-Options: DENY | Clickjacking | Düşük, siteyi iframe içine gömmediğiniz sürece |
Referrer-Policy | Dahili URL'nin dış sitelere sızması | Düşük |
Strict-Transport-Security | SSL stripping ve HTTP'ye downgrade | Preload yaparsanız yüksek |
Content-Security-Policy | XSS, script enjeksiyonu, veri hırsızlığı | Katı başlarsanız yüksek |
Herkesi baş ağrıtan son iki başlıktır. Gerisini bugün güvenle ekleyebilirsiniz.
X-Content-Type-Options ve Referrer-Policy: buradan başlayın
Bu iki satırı web sunucusu yapılandırmasına koyun ve sonraki işe geçin:
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header X-Frame-Options "SAMEORIGIN" always;
Nginx'te always kelimesi önemlidir. Koymazsanız, bu başlıklar 404 ve 500 gibi hata yanıtlarına uygulanmaz ve tam da o hata sayfaları giriş noktası olur. Bunu güvenlik incelemelerinde çok gördüm.
HSTS: preload neden tuzaktır
Strict-Transport-Security başlığı tarayıcıya, belirli bir süre boyunca bu alan adını yalnızca HTTPS ile açmasını söyler. Basittir:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
31536000 sayısı saniye cinsinden bir yıl demektir. Şimdi tuzak: includeSubDomains'i tüm alt alan adlarınızın geçerli HTTPS'e sahip olduğundan emin olduğunuzda koyun. Yalnızca HTTP olan eski bir alt alan adınız varsa, tarayıcı bu başlığı gördüğü andan itibaren, o alt alan adı siteyi daha önce açmış tüm kullanıcılar için erişilemez hale gelir. Ne önbelleği temizleyerek, ne DNS'i değiştirerek. max-age bitene kadar beklemelisiniz.
Ve sonra preload. preload, alan adınızı tarayıcının kendi içine derlenmiş katı listeye kaydetmek demektir. O andan itibaren, ilk ziyaret bile HTTPS'e mecburdur ve artık geri dönüş yolunuz yoktur. Ben preload'u yalnızca en az altı ay HSTS ile sorunsuz çalışmış, tüm alt alan adları HTTPS olan ve başka bir alan adına taşınma planı olmayan alan adları için öneriyorum. Gerisi için, bir yıllık max-age yeterlidir.
Sunucuda hâlâ geçerli sertifikanız yoksa, önce onu düzeltin; SSL hatası ve teşhis yöntemi kılavuzu iyi bir başlangıç noktasıdır. Bozuk HTTPS üzerinde HSTS, yalnızca başarısızlığı hızlandırır.
CSP: en etkili güvenlik başlığı ve en riskli olanı
Content-Security-Policy, XSS'i gerçekten durduran tek başlıktır. Diğer başlıklar savunma katmanıdır; CSP ana duvardır. Ama siteleri beyaza çeviren de tam olarak bu CSP'dir.
Yaygın hata, kişinin bir internet kılavuzundan kopyalayıp şunu koymasıdır:
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
Ve sonra sitesi hiçbiri çalışmayan inline script'lerle dolar. Menü düğmesi çalışmaz, iletişim formu gönderilmez ve hata sunucu logunda değil konsolda olduğu için saatlerce kodda hata arar.
Enforce ile değil, Report-Only ile başlayın
Doğru sıra şudur. Önce raporlama modunda etkinleştirin:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://cdn.example.com; report-uri /csp-report" always;
Tarayıcı hiçbir şeyi bloklamaz, ama ihlal edilen her şeyi o adrese gönderir. Bir hafta log toplayın. O zaman gerçekten hangi alan adlarına ihtiyacınız olduğunu anlarsınız, düşündüklerinize değil. Bir hafta sonra, aynı policy'yi -Report-Only olmadan koyun.
Pratik not: Siteniz WordPress ise, katı CSP neredeyse her zaman eklentileri bozar, çünkü çoğu inline script enjekte eder. CSP'ye dokunmadan önce, önce gereksiz eklentileri kaldırın; wp-config'ten eklentilere WordPress güvenliği kılavuzu tam da bunu adım adım açıklıyor. Sitenizin REST API'si açıksa, o da bir bilgi sızıntısı yoludur ve REST API'den kullanıcı sızıntısı yolunu kapatma ayrıca yapılmalıdır.
nonce ve hash: inline script için doğru yol
Tüm CSP'yi etkisiz kılan 'unsafe-inline' yerine nonce kullanın. Web sunucusu her yanıt için rastgele bir değer üretir ve başlığa koyar:
script-src 'nonce-rAnd0m123' 'strict-dynamic';
Ve aynı değeri script etiketine koyarsınız: <script nonce="rAnd0m123">. Zahmetlidir, ama hem gerçek CSP'ye sahip olmanın hem de inline script'lerin çalışmasının tek yoludur. Site statikse, daha basit olan hash'i kullanın.
Gerçekten işe yarayan sıra
X-Content-Type-Options,Referrer-PolicyveX-Frame-Options'ı bugün ekleyin. Sıfır risk.- HTTPS'i tüm alt alan adlarında düzeltin ve HTTP'den 301 yönlendirmesi koyun.
- HSTS'yi
max-age=300ile başlatın. Bir hafta bekleyin. Sonra bir yıla çıkarın. - CSP'yi
-Report-Onlyile koyun ve bir hafta log toplayın. - Nihai policy'yi enforce edin, inline script'ler için nonce ile.
- preload'u yalnızca altı ay sorunsuz geçtiyse düşünün.
Bu sıraya uyun, çünkü her adım bir sonraki adımın varsayımlarını oluşturur. Inline script'leri temizlemeden önce CSP koyarsanız, yalnızca bir hafta zaman kaybetmiş olursunuz.
Çok göz ardı edilen bir altyapı notu da var: güvenlik başlığı yalnızca web sunucusunda değil, ağ kenarında da ayarlanabilir. Trafik DDoS koruma katmanından geçiyorsa, bu başlıkların bazıları orada da uygulanabilir ve bu, biri doğrudan sunucu IP'sine vursa bile başlıkların kaybolmamasını sağlar. Hacim saldırılarının hedefi olan siteler için bu katman değerlidir.
Ve son olarak: başlıkları denetim loguna kaydedin. Biri policy'yi her değiştirdiğinde, ne zaman ve neden olduğunu bilmelisiniz. Henüz denetim logunuz yoksa, denetim logunu bozulmadan tutma kılavuzunu okuyun; o olmadan, gelecekte bozuk bir CSP'yi hata ayıklamak neredeyse imkânsızdır.
Sık sorulan sorular
CSP ekledikten sonra sitenin bir kısmı neden beyaz oldu?
Çünkü CSP enforce modunda, policy'de yer almayan her kaynağı bloklar ve tarayıcı göstermek yerine onu kaldırır. İlk yapmanız gereken tarayıcı konsolunu açıp Refused to load veya Refused to execute inline script hatasını görmektir. O hata tam olarak hangi alan adının veya hangi inline script'in bloklandığını söyler. Bunu görmeden, policy'deki her değişiklik tahmin etmektir.
HSTS siteyi sonsuza kadar erişilemez kılabilir mi?
Normal durumda hayır, çünkü max-age bittikten sonra tarayıcı tekrar HTTP'ye izin verir. Ama alan adını preload listesine kaydettiyseniz, evet; o liste tarayıcının kendi içindedir ve yeni bir tarayıcı sürümü yayınlanıp kullanıcı güncelleyene kadar silinmez. Bu yüzden preload'u yalnızca yıllarca aynı alan adında kalacağınızdan emin olduğunuz ve tüm alt alan adları HTTPS olan alan adları için öneriyorum.
Güvenlik başlığı firewall veya WAF'ın yerini alır mı?
Hayır. Güvenlik başlığı kullanıcının tarayıcısında çalışır, yani yalnızca tarayıcı üzerinden siteye gelen kullanıcıları etkiler. Doğrudan API'ye vuran veya sunucudan sunucuya olan bir saldırı, bu başlıkların hiçbirini görmez. Başlıklar istemci tarafı savunma katmanıdır ve ağ koruması ile sunucu tarafı kimlik doğrulamanın yerine değil, yanında olmalıdır.
Başlıklarımın doğru ayarlandığını nasıl anlarım?
Alan adı üzerinde curl -sI ile veya çevrimiçi başlık kontrol araçlarıyla. Ama mutlaka birkaç farklı yolu test edin: ana sayfa, bir iç sayfa, bir 404 sayfası ve bir API yanıtı. Çoğu zaman başlıklar yalnızca 200 yanıtlarına uygulanmıştır ve hata sayfaları korumasız kalmıştır. Siteniz birkaç katmanın arkasındaysa, sunucunun içinden değil, ağın dışından test edin.
Yorumlar 0
Henüz yorum yok — ilk siz olun!