İçerik Güvenlik Politikası (CSP) Nedir?
Kısa tanım
İçerik Güvenlik Politikası (CSP, Content Security Policy), bir sayfanın hangi kaynaklardan betik, stil, görsel ve bağlantı yükleyebileceğini ve hangi sitelerin onu çerçeve içinde gösterebileceğini tarayıcıya bildiren bir HTTP yanıt başlığıdır. Tarayıcı politikaya uymayan kaynağı engeller. Özellikle XSS saldırılarında enjekte edilen betiğin çalışmasını zorlaştıran ek bir savunma katmanı olarak kullanılır.
Diğer adları: Content Security Policy, CSP, Content-Security-Policy başlığı, CSP başlığı

Tarayıcıya verilen bir izin listesi
Bir web sayfası varsayılan olarak her yerden betik çalıştırabilir, her alan adına istek gönderebilir ve her site tarafından iframe içine alınabilir. CSP bu serbestliği daraltır. Sunucu, Content-Security-Policy HTTP başlığı ile bir kural seti gönderir; tarayıcı sayfa boyunca bu kurallara uymayan her kaynağı engeller ve konsola bir ihlal kaydı yazar. CSP'nin asıl hedefi XSS'tir: bir saldırgan sayfaya betik enjekte etmeyi başarsa bile, o betik politikanın izin verdiği bir kaynaktan gelmiyorsa çalışmaz.
Sık kullanılan yönergeler
| Yönerge | Neyi denetler? |
|---|---|
default-src | Ayrıca belirtilmeyen kaynak türleri için varsayılan kural |
script-src | JavaScript kaynakları; politikanın en kritik parçası |
style-src, img-src, font-src | Stil, görsel ve font kaynakları |
connect-src | fetch, XHR ve WebSocket bağlantılarının gidebileceği adresler |
frame-ancestors | Sayfayı hangi sitelerin çerçeveleyebileceği; clickjacking'e karşı X-Frame-Options'ın esnek karşılığı |
object-src, base-uri | Eklenti içerikleri ve <base> etiketi; katı politikalarda genellikle 'none' |
upgrade-insecure-requests | Sayfa içindeki HTTP kaynak isteklerini HTTPS'e yükseltir |
Alan adı listesi yerine nonce
İlk akla gelen yöntem, güvenilen alan adlarını tek tek listelemektir. Pratikte bu tür politikalar sık sık delik bırakır: izin verilen büyük bir CDN ya da analiz alan adı, saldırganın da kullanabileceği betikler barındırabilir. Bu yüzden önerilen yaklaşım "katı CSP"dir. Sunucu her yanıtta tahmin edilemez, rastgele bir nonce üretir, bunu hem başlığa hem de meşru <script> etiketlerine yazar:
Content-Security-Policy: script-src 'nonce-k9Qz2xL7' 'strict-dynamic'; object-src 'none'; base-uri 'none'
<script nonce="k9Qz2xL7" src="/js/uygulama.js"></script>Nonce'u bilmeyen enjekte edilmiş bir betik çalışmaz. 'strict-dynamic', nonce taşıyan bir betiğin yüklediği diğer betiklere de güvenilmesini sağlar; üçüncü taraf etiket yöneticileriyle çalışmayı kolaylaştırır ama güveni zincirleme genişlettiği için bilinçli kullanılmalıdır. Statik sayfalarda nonce yerine, satır içi betiğin içeriğinden hesaplanan 'sha256-…' özetleri kullanılabilir. Nonce ya da hash bulunduğunda tarayıcılar 'unsafe-inline' ifadesini yok sayar; bu ifadeyi tek başına kullanmak ise CSP'nin XSS korumasını büyük ölçüde boşa çıkarır.
Önce raporla, sonra uygula
Çalışan bir siteye doğrudan katı bir CSP koymak; analitik, sohbet balonu ya da ödeme formu gibi parçaları sessizce bozabilir. Güvenli yol, politikayı önce Content-Security-Policy-Report-Only başlığıyla göndermektir. Bu başlıkta tarayıcı hiçbir şeyi engellemez, yalnızca ihlalleri report-to (ya da eski report-uri) ile belirtilen adrese bildirir. Toplanan raporlar temizlenip meşru kaynaklar politikaya eklendikten sonra aynı kurallar uygulanan başlığa taşınır. Yönergelerin güncel listesi MDN CSP rehberinde bulunur.
CSP neyi çözmez?
CSP bir ikinci savunma hattıdır. Kullanıcı verisini HTML'e güvenli biçimde kodlamanın yerini tutmaz; politika gevşek yazıldığında ya da izin verilen bir kaynak ele geçirildiğinde XSS yine mümkündür. HTML enjeksiyonu yoluyla sayfanın görünümünü değiştirmek veya kullanıcıyı yanıltmak gibi betik gerektirmeyen saldırıları da tamamen durdurmaz. CSP, diğer güvenlik başlıklarıyla birlikte düşünülmelidir. Ayrıca <meta http-equiv> ile tanımlanan bir CSP'de frame-ancestors, report-uri ve sandbox yönergeleri desteklenmez; bu yüzden politika mümkünse HTTP başlığıyla gönderilmelidir.

