Web'in güvenlik modelinin kökü aynı kaynak politikasına dayanır. https://mybank.com
kodundan gelen kod yalnızca https://mybank.com
verilerine erişmeli ve https://evil.example.com
koduna hiçbir zaman erişim izni verilmemelidir.
Her kaynak, web'in geri kalanından izole edilerek geliştiricilere uygulama oluşturma ve oynama için güvenli bir korumalı alan sağlar. Teoride, bu mükemmel bir parlaklık. Uygulamada, saldırganlar sistemi tersine çevirmenin akıllı yollarını bulmuşlardır.
Örneğin, siteler arası komut dosyası çalıştırma (XSS) saldırıları, bir siteyi amaçlanan içerikle birlikte kötü amaçlı kod iletmesi için kandırarak aynı kaynak politikasını atlar. Tarayıcılar, bir sayfada gösterilen tüm koda söz konusu sayfanın güvenlik kaynağının meşru bir parçası olarak güvendiğinden, bu büyük bir sorundur. XSS Hile Bildirimi, bir saldırganın kötü amaçlı kod yerleştirerek bu güveni ihlal etmek için kullanabileceği yöntemlerin eski ancak temsili bir kesitidir. Bir saldırgan herhangi bir kodu başarılı bir şekilde yerleştirirse oyun bitmiş demektir. Bu, kullanıcı oturumu verilerinin ele geçirilmesi anlamına gelir ve gizli tutulması gereken bilgiler The Bad Guys'a sızdırılır. Mümkünse bunu önlemek isteriz.
Bu genel bakışta, modern tarayıcılarda XSS saldırılarının riskini ve etkisini önemli ölçüde azaltabilecek bir savunma özelliği vurgulanmaktadır: İçerik Güvenliği Politikası (İGP).
Özet
- İzin verilen ve verilmeyen içerikler hakkında müşteriye bilgi vermek için izin verilenler listelerini kullanın.
- Hangi yönergelerin kullanılabileceğini öğrenin.
- Kullandıkları anahtar kelimeleri öğrenin.
- Satır içi kod ve
eval()
zararlı kabul edilir. - Politika ihlallerini zorunlu kılmadan önce sunucunuza bildirin.
Kaynak izin verilenler listeleri
XSS saldırılarının kötü amaçla kullandığı sorun, tarayıcının uygulamanızın parçası olan komut dosyası ile bir üçüncü tarafça yerleştirilen komut dosyası arasında ayrım yapamamasıdır. Örneğin, bu sayfanın alt kısmında yer alan Google +1 düğmesi, bu sayfanın kaynağı bağlamında https://apis.google.com/js/plusone.js
kaynağından gelen kodu yükleyip yürütür. Bu koda güveniyoruz, ancak tarayıcının apis.google.com
kodundan gelen kodun muhteşem olduğunu, apis.evil.example.com
tarafından sağlanan kodun ise iyi olmadığını kendi başına belirlemesini bekleyemeyiz. Tarayıcı, kaynaktan bağımsız olarak sayfanın istediği tüm kodları memnuniyetle indirir ve yürütür.
CSP, bir sunucunun sunduğu her şeye körü körüne güvenmek yerine, güvenilir içerik
kaynaklarını içeren bir izin verilenler listesi oluşturmanıza olanak tanıyan ve tarayıcıya yalnızca bu kaynaklardaki kaynakları
yürütmesi veya oluşturması talimatını veren Content-Security-Policy
HTTP üst bilgisini tanımlar. Bir saldırgan, komut dosyasının yerleştirileceği bir delik bulsa bile komut dosyası, izin verilenler listesiyle eşleşmez ve dolayısıyla yürütülmez.
Geçerli kod sunma konusunda apis.google.com
uygulamasına güvendiğimize ve aynısını yapacağına güvendiğimizden, komut dosyasının yalnızca bu iki kaynaktan birinden geldiğinde yürütülmesine izin veren bir politika tanımlayalım:
Content-Security-Policy: script-src 'self' https://apis.google.com
Basit, değil mi? Muhtemelen tahmin ettiğiniz gibi script-src
, belirli bir sayfa için komut dosyasıyla ilgili bir dizi ayrıcalığı kontrol eden bir yönergedir. Geçerli bir komut dosyası kaynağı olarak 'self'
ve başka bir komut dosyası kaynağı olarak https://apis.google.com
tanımladık. Tarayıcı, JavaScript'i güvenli bir şekilde apis.google.com
bağlantısından HTTPS üzerinden
ve geçerli sayfanın kaynağından indirir ve yürütür.
![Konsol hatası: "http://evil.example.com/evil.js" komut dosyasının yüklenmesi, şu İçerik Güvenliği Politikası yönergesini ihlal ettiği için reddedildi: script-src "self" https://apis.google.com](https://developer.chrome.com/static/docs/privacy-security/csp/image/console-error-refused-l-524026adbb83a.png?authuser=5&hl=tr)
Bu politika tanımlandığında, tarayıcı başka bir kaynaktan komut dosyası yüklemek yerine bir hata bildirir. Akıllı bir saldırgan, sitenize kod yerleştirmeyi başardığında, beklediği başarıdan çok bir hata mesajıyla karşılaşır.
Politika, çok çeşitli kaynaklar için geçerlidir
Komut dosyası kaynakları en bariz güvenlik riskleri olsa da CSP, bir sayfanın yüklemesine izin verilen kaynaklar üzerinde oldukça ayrıntılı kontrol sağlayan zengin bir politika yönergesi grubu sağlar. Daha önce script-src
görmüştünüz, o yüzden konsept açık olmalıdır.
Geri kalan kaynak yönergelerinin üzerinden geçelim. Aşağıdaki liste, 2. seviye itibarıyla yönergelerin durumunu temsil etmektedir. 3. düzey spesifikasyon yayınlanmış olup, önde gelen tarayıcılarda büyük ölçüde uygulanmamaktadır.
base-uri
, bir sayfanın<base>
öğesinde görünebilecek URL'leri kısıtlar.child-src
, çalışanların ve yerleştirilmiş çerçeve içeriklerinin URL'lerini listeler. Örneğin:child-src https://youtube.com
, YouTube'dan video yerleştirmeyi etkinleştirir ancak diğer kaynaklardan video yerleştirmeyi etkinleştirir.connect-src
, bağlanabileceğiniz kaynakları (XHR, WebSockets ve EventSource aracılığıyla) sınırlandırır.font-src
, web yazı tipleri sunabilen kaynakları belirtir. Google'ın web yazı tiplerifont-src https://themes.googleusercontent.com
aracılığıyla etkinleştirilebilir.form-action
,<form>
etiketlerinden gönderim için geçerli uç noktaları listeler.frame-ancestors
, geçerli sayfayı yerleştirebilecek kaynakları belirtir. Bu yönerge<frame>
,<iframe>
,<embed>
ve<applet>
etiketleri için geçerlidir. Bu yönerge<meta>
etiketlerinde kullanılamaz ve yalnızca HTML olmayan kaynaklar için geçerlidir.frame-src
2. düzeyde kullanımdan kaldırıldı ancak 3. düzeyde geri yüklendi. Yoksa önceden olduğu gibichild-src
değerine geri döner.img-src
, görüntülerin yüklenebileceği kaynakları tanımlar.media-src
, video ve ses yayınlamasına izin verilen kaynakları kısıtlar.object-src
, Flash ve diğer eklentiler üzerinde kontrol olanağı sağlar.plugin-types
, bir sayfanın çağırabileceği eklenti türlerini sınırlar.report-uri
, bir içerik güvenliği politikası ihlal edildiğinde tarayıcının rapor göndereceği URL'yi belirtir. Bu yönerge<meta>
etiketlerinde kullanılamaz.style-src
,script-src
'in stil sayfalarında eşdeğeridir.upgrade-insecure-requests
, kullanıcı aracılarına HTTP'yi HTTPS'ye dönüştürerek URL şemalarını yeniden yazmalarını söyler. Bu yönerge, yeniden yazılması gereken çok sayıda eski URL'ye sahip web siteleri içindir.worker-src
; çalışan, paylaşılan çalışan veya hizmet çalışanı olarak yüklenebilecek URL'leri kısıtlayan bir CSP Düzey 3 yönergesidir. Temmuz 2017 itibarıyla bu yönergenin uygulamaları sınırlıdır.
Varsayılan olarak, yönergeler geniş kapsamlıdır. Bir yönerge için belirli bir politika ayarlamazsanız (ör. font-src
), bu yönerge varsayılan olarak *
değerini geçerli kaynak olarak belirlemişsiniz gibi davranır (örneğin, yazı tiplerini kısıtlama olmadan herhangi bir yerden yükleyebilirsiniz).
Bir default-src
yönergesi belirterek bu varsayılan davranışı geçersiz kılabilirsiniz. Bu yönerge, belirtmeden bıraktığınız çoğu yönerge için varsayılanları tanımlar. Genellikle bu, -src
ile biten tüm yönergeler için geçerlidir. default-src
, https://example.com
olarak ayarlanırsa ve bir font-src
yönergesi belirtemezseniz https://example.com
alanındaki yazı tiplerini yükleyebilirsiniz. Önceki örneklerimizde yalnızca script-src
belirtmiştik. Bu, resimlerin, yazı tiplerinin ve diğer öğelerin her kaynaktan yüklenebildiği anlamına gelir.
Aşağıdaki yönergeler yedek olarak default-src
kullanmaz. Unutmayın, bunları ayarlamamanın
her şeye izin vermekle aynı şey olduğunu unutmayın.
base-uri
form-action
frame-ancestors
plugin-types
report-uri
sandbox
Kendi uygulamanız için anlamlı olan istediğiniz kadar çok veya az yönerge kullanabilirsiniz. Bunun için her birini HTTP başlığında listelemeniz ve yönergeleri noktalı virgülle ayırmanız yeterlidir. Belirli bir türdeki tüm gerekli kaynakları tek bir yönergede listelediğinizden emin olun. script-src https://host1.com; script-src https://host2.com
gibi bir şey yazarsanız ikinci yönerge yok sayılır. Aşağıdaki gibi bir ifade her iki kaynağı da doğru bir şekilde geçerli olarak belirtir:
script-src https://host1.com https://host2.com
Örneğin, tüm kaynaklarını bir içerik yayınlama ağından yükleyen (ör. https://cdn.example.net
) bir uygulamanız varsa ve çerçeveli içeriğe veya eklentilere ihtiyacınız olmadığını biliyorsanız politikanız aşağıdaki gibi görünebilir:
Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'
Uygulama ayrıntıları
Web'deki çeşitli eğiticilerde X-WebKit-CSP
ve X-Content-Security-Policy
başlıklarını göreceksiniz. Bundan sonra, bu önekli başlıkları göz ardı etmelisiniz. Modern tarayıcılar (IE hariç) ön eksiz Content-Security-Policy
üst bilgisini destekler. Kullanmanız gereken başlık budur.
Politika, kullandığınız başlıktan bağımsız olarak sayfa bazında tanımlanır: Korunmasını istediğiniz her yanıtla birlikte HTTP üstbilgisini göndermeniz gerekir. Bu, belirli sayfalarla ilgili olarak politikaların özel ihtiyaçlarına göre ince ayar yapabileceğiniz için çok esneklik sağlar. Sitenizdeki sayfalardan birinde +1 düğmesi bulunurken bazılarında yoktur: Düğme kodunun yalnızca gerekli olduğunda yüklenmesine izin verebilirsiniz.
Her yönergedeki kaynak listesi esnektir. Kaynakları şemaya (data:
, https:
) göre veya yalnızca ana makine adına (example.com
, o ana makinedeki her kaynakla eşleşen şema, herhangi bir bağlantı noktası) veya tam nitelikli bir URI'ye (https://example.com:443
, yalnızca HTTPS ile eşleşen, yalnızca example.com
ve yalnızca bağlantı noktası 443) kadar belirlilik içerecek şekilde belirtebilirsiniz. Joker karakterler yalnızca bir şema, bağlantı noktası veya ana makine adının en soldaki konumunda kabul edilir. *://*.example.com:*
, herhangi bir bağlantı noktasında herhangi bir şema kullanılarak example.com
alanının tüm alt alan adlarıyla (example.com
kendisi değil) eşleşir.
Kaynak liste dört anahtar kelime de kabul eder:
'none'
, bekleyebileceğiniz gibi hiçbir şeyle eşleşmiyor.'self'
mevcut kaynakla eşleşiyor ancak alt alan adıyla eşleşmiyor.'unsafe-inline'
, satır içi JavaScript ve CSS'ye izin verir. (Buna birazdan daha ayrıntılı bir şekilde değineceğiz.)'unsafe-eval'
,eval
gibi metin-JavaScript mekanizmalarına izin verir. (Buna da başlayalım.)
Bu anahtar kelimeler için tek tırnak işareti gerekir. Örneğin, script-src 'self'
(tırnak işaretiyle) mevcut ana makineden JavaScript'in yürütülmesini yetkilendirir; script-src self
(tırnak işareti olmadan) "self
" adlı bir sunucudan JavaScript'e izin verir (ve geçerli ana makineden değil).
Bu da büyük olasılıkla kastettiğiniz şey değildir.
Korumalı alana alma
Bahsetmeye değer bir yönerge daha var: sandbox
. Sayfanın yükleyebileceği kaynaklar yerine sayfanın yapabileceği işlemlere kısıtlama getirdiği için daha önce incelediğimizden biraz farklıdır. sandbox
yönergesi mevcutsa sayfa, sandbox
özelliğine sahip bir <iframe>
öğesinin içinde yüklenmiş gibi değerlendirilir. Bunun sayfa üzerinde çok çeşitli etkileri olabilir: sayfayı benzersiz bir kaynağa zorlamak ve form göndermeyi önlemek. Bu, bu makalenin kapsamı dışındadır ancak geçerli korumalı alan özellikleriyle ilgili tüm ayrıntıları HTML5 spesifikasyonunun "Korumalı Alan" bölümünde bulabilirsiniz.
Meta etiket
İGP'nin tercih edilen yayınlanma mekanizması bir HTTP başlığıdır. Bununla birlikte, bir sayfada doğrudan işaretlemeden politika ayarlamak faydalı olabilir. Bunu, http-equiv
özelliğine sahip bir <meta>
etiketi kullanarak yapın:
<meta
http-equiv="Content-Security-Policy"
content="default-src https://cdn.example.net; child-src 'none'; object-src 'none'"
/>
Bu kod frame-ancestors
, report-uri
veya sandbox
için kullanılamaz.
Satır içi kod zararlı kabul edildi
CSP'nin izin verilenler listesindeki kaynakları temel aldığı açık olmalıdır. Bu, tarayıcıya belirli kaynak gruplarını kabul edilebilir olarak işlemesi ve geri kalanını reddetmesi için talimat vermenin açık bir yoludur. Kaynak tabanlı izin verilenler listeleri, XSS saldırılarının ortaya çıkardığı en büyük tehdidi, yani satır içi komut dosyası yerleştirmeyi çözemez.
Bir saldırgan, doğrudan kötü amaçlı yük (<script>sendMyDataToEvilDotCom();</script>
) içeren bir komut dosyası etiketi yerleştirebilir. Bu durumda, tarayıcının bu etiketi geçerli bir satır içi komut dosyası etiketinden ayırt etmesini sağlayacak bir mekanizma yoktur. CSP bu sorunu satır içi komut dosyasını tamamen yasaklayarak çözer:
Emin olmanın tek yolu budur.
Bu yasak, yalnızca doğrudan script
etiketlerine yerleştirilmiş komut dosyalarını değil, aynı zamanda satır içi etkinlik işleyicileri ve javascript:
URL'leri de içerir. script
etiketlerinin içeriğini harici bir dosyaya taşımanız ve javascript:
URL'leri ve <a ... onclick="[JAVASCRIPT]">
öğelerini uygun addEventListener()
çağrılarıyla değiştirmeniz gerekir. Örneğin, aşağıdaki cümleyi şuradan yeniden yazabilirsiniz:
<script>
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>
şuna benzer bir şekilde değiştirebilirsiniz:
<!-- amazing.html -->
<script src="amazing.js"></script>
<button id="amazing">Am I amazing?</button>
<div style="clear:both;"></div>
// amazing.js
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('amazing').addEventListener('click', doAmazingThings);
});
Yeniden yazılan kodun İGP ile iyi çalışmanın ötesinde birçok avantajı vardır. Bu, CSP kullanımınızdan bağımsız olarak zaten en iyi uygulamadır. Satır içi JavaScript, yapı ve davranışı tam olarak istemediğiniz şekilde bir araya getirir. Harici kaynaklar tarayıcıların önbelleğe alması daha kolaydır, geliştiriciler tarafından daha anlaşılır ve derleme ile sadeleştirmeye elverişlidir. Kodu harici kaynaklara taşıma işini yaparsanız daha iyi kod yazarsınız.
Satır içi stil de aynı şekilde ele alınır: CSS'nin sağladığı şaşırtıcı derecede zekice veri hırsızlığı yöntemlerine karşı koruma sağlamak için hem style
özelliği hem de style
etiketleri harici stil sayfalarında birleştirilebilir.
Satır içi komut dosyanız ve stilinizin olması gerekiyorsa bunu, script-src
veya style-src
yönergesinde izin verilen kaynak olarak 'unsafe-inline'
ekleyerek etkinleştirebilirsiniz. Sıfır veya karma değeri de kullanabilirsiniz (aşağıya bakın), ancak kullanmamanız gerekir.
Satır içi komut dosyasının yasaklanması CSP'nin sağladığı en büyük güvenlik kazanma yöntemidir ve satır içi stilin yasaklanması aynı şekilde uygulamanızı güçlendirir. Tüm kodu satır dışına taşıdıktan sonra her şeyin doğru bir şekilde çalışmasını sağlamak için biraz çaba sarf etmek gerekse de bu çabanın karşılığını alırsınız.
Kesinlikle kullanmanız gerekiyorsa
CSP Seviye 2, kriptografik bir tek seferlik rastgele sayı (bir kez kullanılır) veya karma kullanarak belirli satır içi komut dosyalarını izin verilenler listesine eklemenize olanak tanıyarak satır içi komut dosyaları için geriye dönük uyumluluk sunar. Bu zahmetli olsa da biraz zahmetsizce faydalıdır.
Tek seferlik rastgele sayı kullanmak için komut dosyası etiketinize bir nonce özelliği verin. Değeri, güvenilir kaynaklar listesindeki biriyle eşleşmelidir. Örneğin:
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
// Some inline code I can't remove yet, but need to asap.
</script>
Şimdi, tek seferlik rastgele değerini nonce-
anahtar kelimesine eklenen script-src
yönergenize ekleyin.
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
Noce'ların her sayfa isteği için yeniden oluşturulması ve tahmin edilemez olması gerektiğini unutmayın.
Karmalar da hemen hemen aynı şekilde çalışır. Komut dosyası etiketine kod eklemek yerine, komut dosyasının kendisinin SHA karmasını oluşturun ve bunu script-src
yönergesine ekleyin.
Örneğin, sayfanızda şunları içerdiğini varsayalım:
<script>
alert('Hello, world.');
</script>
Politikanız şunları içerecektir:
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
Burada dikkat edilmesi gereken birkaç nokta var. sha*-
öneki, karmayı oluşturan algoritmayı belirtir. Yukarıdaki örnekte sha256-
kullanılmıştır. CSP, sha384-
ve sha512-
'ı da destekler. Karmayı oluştururken <script>
etiketlerini dahil etmeyin. Baştaki veya sondaki boşluklar da dahil olmak üzere, büyük harf ve boşluk kullanımı da önemlidir.
SHA karmaları oluşturmayla ilgili bir Google araması, sizi istediğiniz sayıda dilde çözümlere yönlendirir. Chrome 40 veya sonraki bir sürümünü kullanarak Geliştirici Araçları'nı açıp sayfanızı yeniden yükleyebilirsiniz. Konsol sekmesi, satır içi komut dosyalarınızın her biri için doğru sha256 karmasına sahip hata mesajları içerir.
Eval da
Saldırganlar doğrudan komut dosyası yerleştiremese bile, uygulamanızı kandırarak metni yürütülebilir JavaScript'e dönüştürebilir ve kendi adlarına yürütebilirler. eval()
, new
Function() , setTimeout([string], ...)
ve
setInterval([string], ...)
, yerleştirilen metnin beklenmedik
bir şekilde kötü amaçlı bir şey yürütebileceği vektörlerdir. CSP'nin bu riske varsayılan yanıtı, tüm bu vektörleri tamamen engellemektir.
Bunun uygulama derleme şekliniz üzerinde birden fazla etkisi vardır:
eval
öğesine güvenmek yerine, yerleşikJSON.parse
aracılığıyla JSON'ı ayrıştırmanız gerekir. Yerel JSON işlemleri IE8'den beri her tarayıcıda kullanılabilir ve tamamen güvenlidir.- Yapmakta olduğunuz
setTimeout
veyasetInterval
çağrılarını dizeler yerine satır içi işlevlerle yeniden yazın. Örneğin:
setTimeout("document.querySelector('a').style.display = 'none';", 10);
şu şekilde yazılması daha iyi olurdu:
setTimeout(function () {
document.querySelector('a').style.display = 'none';
}, 10);
- Çalışma zamanında satır içi şablon oluşturmaktan kaçının: Birçok şablon oluşturma kitaplığı, çalışma zamanında şablon oluşturma işlemini hızlandırmak için
new Function()
hizmetini serbest bir şekilde kullanır. Bu, dinamik programlamanın kullanışlı bir uygulamasıdır ancak kötü amaçlı metinleri değerlendirme riskiyle karşı karşıyadır. Bazı çerçeveler CSP'yi kullanıma hazır şekilde destekler veeval
yokluğunda sağlam bir ayrıştırıcı kullanılır. AngularJS'nin ng-csp yönergesi bunun iyi bir örneğidir.
Ancak önceden derleme sunan bir şablon dili kullanmak daha iyi bir seçenektir (ör. Gidon çubukları kullanır). Şablonlarınızı önceden derlemek, kullanıcı deneyimini en hızlı çalışma zamanı uygulamasından daha hızlı bir hale getirebilir ve aynı zamanda daha güvenlidir. "eval" ve "metinden JavaScript'e" işlevleri uygulamanız için gerekliyse bunları, script-src
yönergesinde 'unsafe-eval'
öğesini izin verilen kaynak olarak ekleyerek etkinleştirebilirsiniz. Ancak bunu kesinlikle önermiyoruz. Dizeleri yürütme özelliğini yasaklamak, bir saldırganın sitenizde yetkisiz kod yürütmesini çok daha zorlaştırır.
Raporlama
CSP'nin güvenilmeyen kaynakları istemci tarafında engelleme özelliği kullanıcılarınız için büyük bir kazançtır ancak sunucuya bir tür bildirim gönderilmesi çok faydalı olur. Böylece, kötü amaçlı yerleştirmeye izin veren hataları daha en başta tanımlayıp düzeltebilirsiniz. Bu amaçla, tarayıcıya JSON biçimli ihlal raporlarını report-uri
yönergesinde belirtilen bir konuma göre POST
talimatını verebilirsiniz.
Content-Security-Policy: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
Bu raporlar aşağıdaki gibi görünür:
{
"csp-report": {
"document-uri": "http://example.org/page.html",
"referrer": "http://evil.example.com/",
"blocked-uri": "http://evil.example.com/evil.js",
"violated-directive": "script-src 'self' https://apis.google.com",
"original-policy": "script-src 'self' https://apis.google.com; report-uri http://example.org/my_amazing_csp_report_parser"
}
}
Bu, ihlalin meydana geldiği sayfa (document-uri
), söz konusu sayfanın yönlendireni (HTTP üst bilgisi alanından farklı olarak anahtarın yanlış yazılmadığını unutmayın), sayfanın politikasını (blocked-uri
) ihlal eden kaynak, ihlal ettiği belirli yönerge (violated-directive
) ve sayfanın tam politikası (original-policy
) dahil olmak üzere ihlalin nedenini tespit etmenize yardımcı olacak çok sayıda bilgi içerir.
Yalnızca Rapor
CSP'yi kullanmaya yeni başlıyorsanız kullanıcılarınıza acımasız bir politika sunmadan önce uygulamanızın mevcut durumunu değerlendirmek faydalı olacaktır.
Eksiksiz bir dağıtıma giden yolda bir adım olarak, tarayıcıdan bir politikayı izlemesini, ihlalleri bildirmesini ancak kısıtlamaları uygulamamasını isteyebilirsiniz. Content-Security-Policy
üstbilgisi göndermek yerine Content-Security-Policy-Report-Only
üstbilgisi gönderin.
Content-Security-Policy-Report-Only: default-src 'self'; ...; report-uri /my_amazing_csp_report_parser;
Yalnızca rapor modunda belirtilen politika, kısıtlanmış kaynakları engellemez ancak belirttiğiniz konuma ihlal raporları gönderir. Hatta her iki üstbilgiyi de göndererek bir politikayı zorunlu kılarken diğerini de izleyebilirsiniz. Bu, uygulamanızın İGP'sindeki değişikliklerin etkisini değerlendirmenin harika bir yoludur: Yeni bir politika için bildirme özelliğini etkinleştirin, ihlal raporlarını izleyin ve ortaya çıkan hataları düzeltin. Etkisinden memnun kaldığınızda yeni politikayı uygulamaya başlayın.
Gerçek Dünyada Kullanım
CSP 1; Chrome, Safari ve Firefox'ta oldukça kullanılabilir ancak IE 10'da çok sınırlıdır. Ayrıntılı bilgileri caniuse.com adresinden görüntüleyebilirsiniz. CSP Düzeyi 2, Chrome'da 40 sürümünden itibaren kullanılmaktadır. Twitter ve Facebook gibi devasa siteler başlığı dağıttı (Twitter'ın örnek olayı okunmaya değer) ve standart, kendi sitelerinizde dağıtım yapmaya başlamanız için çok daha hazır.
Uygulamanız için politika oluşturmanın ilk adımı, gerçekten yüklediğiniz kaynakları değerlendirmektir. Uygulamanızda öğelerin nasıl bir araya getirileceğine hakim olduğunuzu düşünüyorsanız bu gereksinimlere göre bir politika oluşturun. Şimdi birkaç yaygın kullanım alanından bahsedelim ve bunları CSP'nin koruyucu sınırları içinde en iyi şekilde nasıl destekleyebileceğimizi belirleyelim.
1. kullanım alanı: Sosyal medya widget'ları
Google'ın +1 düğmesi
https://apis.google.com
kaynağından bir komut dosyası içerir vehttps://plusone.google.com
kaynağından bir<iframe>
yerleştirir. Düğmeyi yerleştirmek için bu iki kaynağı da içeren bir politikaya ihtiyacınız vardır. Minimum politikascript-src https://apis.google.com; child-src https://plusone.google.com
olmalıdır. Ayrıca, Google'ın sağladığı JavaScript snippet'inin harici bir JavaScript dosyasına alındığından emin olmanız gerekir.frame-src
kullanan 1. Seviyeye dayalı bir politikanız varsa 2. Seviyeyichild-src
olarak değiştirmeniz gerekiyordu. Bu artık İGP Düzey 3'te gerekli değildir.Facebook'un Beğen düğmesi pek çok uygulama seçeneği içerir. Sitenizin geri kalanında güvenli bir şekilde korumalı alana alındığından
<iframe>
sürümünü kullanmaya devam etmenizi öneririz. Düzgün çalışması içinchild-src https://facebook.com
yönergesi gerekir. Varsayılan olarak, Facebook'un sağladığı<iframe>
kodunun göreli bir URL (//facebook.com
) yüklediğini unutmayın. HTTPS'yi açıkça belirtmek için bunu değiştirin:https://facebook.com
. Zorunlu değilse HTTP kullanmanız gerekmez.Twitter'ın Tweet düğmesi, her ikisi de
https://platform.twitter.com
adresinde barındırılan bir komut dosyasına ve çerçeveye erişebilir. (Twitter da aynı şekilde varsayılan olarak göreli bir URL sağlar; kodu, yerel olarak kopyalarken/yapıştırırken HTTPS'yi belirtecek şekilde düzenleyin.) Twitter'ın sağladığı JavaScript snippet'ini harici bir JavaScript dosyasına taşıdığınız sürecescript-src https://platform.twitter.com; child-src https://platform.twitter.com
ile her şey hazır olur.Diğer platformlar da benzer şartlara sahiptir ve benzer şekilde ele alınabilir. Yalnızca
'none'
içindefault-src
ayarlamanızı ve widget'ların çalışması için etkinleştirmeniz gereken kaynakları belirlemek üzere konsolunuzu izlemenizi öneririz.
Birden fazla widget eklemek kolaydır: Tek bir türdeki tüm kaynakları tek bir yönergede birleştirmeyi göz önünde bulundurarak politika yönergelerini birleştirin. Üç sosyal medya widget'ını da kullanmak isterseniz politika şöyle görünürdü:
script-src https://apis.google.com https://platform.twitter.com; child-src https://plusone.google.com https://facebook.com https://platform.twitter.com
2. kullanım alanı: Tam kilitleme
Bir bankacılık sitesi işlettiğinizi ve yalnızca sizin yazdığınız kaynakların
yüklenebileceğinden emin olmak istediğinizi varsayalım. Bu senaryoda, kesinlikle her şeyi (default-src 'none'
) engelleyen varsayılan bir politikayla başlayın ve politikanızı buradan devam ettirin.
Bankanın tüm resimleri, stilleri ve komut dosyasını https://cdn.mybank.net
adresindeki bir CDN'den yüklediğini ve çeşitli veri parçalarını aşağı çekmek için XHR üzerinden https://api.mybank.com/
ağına bağlandığını varsayalım. Çerçeveler yalnızca sitedeki yerel sayfalar (üçüncü taraf kaynaklar değil) için kullanılır. Sitede Flash yok, yazı tipi veya ekstra yok. Gönderebileceğimiz en kısıtlayıcı CSP başlığı şudur:
Content-Security-Policy: default-src 'none'; script-src https://cdn.mybank.net; style-src https://cdn.mybank.net; img-src https://cdn.mybank.net; connect-src https://api.mybank.com; child-src 'self'
3. Kullanım alanı: Yalnızca SSL
Alyans tartışma forumu yöneticisi, tüm kaynakların yalnızca güvenli kanallar aracılığıyla yüklendiğinden, ancak gerçekte fazla kod yazmadığından emin olmak istiyor. Bu nedenle, üçüncü taraf forum yazılımının satır içi komut dosyası ve stille dolu büyük parçalarını yeniden yazmak, kendisinin yapabileceklerinin ötesinde bir şey. Aşağıdaki politika geçerli olur:
Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'
default-src
içinde https:
belirtilmiş olsa bile, komut dosyası ve stil yönergeleri bu kaynağı otomatik olarak devralmaz. Her yönerge, söz konusu kaynak türü için tamamen varsayılanın üzerine yazar.
Gelecek
İçerik Güvenliği Politikası Düzey 2, bir Aday Önerisidir. W3C'nin Web Uygulaması Güvenliği Çalışma Grubu, spesifikasyonun bir sonraki yinelemesi olan İçerik Güvenliği Politikası Düzey 3 üzerinde çalışmaya başladı.
Yakında kullanıma sunulacak bu özelliklerle ilgili tartışmayı ilginizi çekiyorsa public-webappsec@ posta listesi arşivlerine göz atın veya kendiniz katılın.