Web'in güvenlik modeli, aynı kaynak politikasına dayanır. https://mybank.com
'den gelen kod yalnızca https://mybank.com
'nin verilerine erişebilmelidir ve https://evil.example.com
'ye kesinlikle erişim izni verilmemelidir.
Her kaynak, web'in geri kalanından izole edilir. Bu sayede geliştiricilere, uygulama geliştirip oynayabilecekleri güvenli bir korumalı alan sunulur. Teoride bu mükemmel bir fikirdir. 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 kandırarak istenen içerikle birlikte kötü amaçlı kod yayınlamaya zorlayarak aynı kaynak politikasını atlar. Tarayıcılar, bir sayfada gösterilen tüm koda, sayfanın güvenlik kaynağının meşru bir parçası olarak güvendiği için bu büyük bir sorundur. XSS Şifre Defteri, saldırganların kötü amaçlı kod ekleyerek bu güveni ihlal etmek için kullanabileceği yöntemlerin eski ancak temsili bir kesitini sunar. 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 bu durumu önlemek isteriz.
Bu genel bakış, modern tarayıcılarda XSS saldırılarının riskini ve etkisini önemli ölçüde azaltabilecek bir savunmayı vurgulamaktadır: İçerik Güvenliği Politikası (CSP).
Özet
- İzin verilenler listelerini kullanarak müşteriye nelere izin verildiğini ve nelere verilmediğini bildirin.
- Hangi yönergelerin kullanılabildiğini öğrenin.
- Hangi anahtar kelimelerin alındığını öğrenin.
- Satır içi kod ve
eval()
zararlı olarak kabul edilir. - Politika ihlallerini uygulamadan önce sunucunuza bildirin.
Kaynak izin listeleri
XSS saldırılarının istismar ettiği sorun, tarayıcının uygulamanızın bir parçası olan komut dosyası ile üçüncü taraflarca kötü amaçlı olarak yerleştirilen komut dosyası arasında ayrım yapamaması. Örneğin, bu sayfanın alt kısmındaki Google +1 düğmesi, bu sayfanın kaynağı bağlamında https://apis.google.com/js/plusone.js
kaynağından gelen kodu yükler ve yürütür. Bu koda güveniriz ancak tarayıcının, apis.google.com
'ten gelen kodun muhtemelen iyi, apis.evil.example.com
'ten gelen kodun ise muhtemelen kötü olduğunu kendi başına anlamasını bekleyemeyiz. Tarayıcı, kaynaktan bağımsız olarak bir sayfanın istediği tüm kodları indirip çalıştırır.
Sunucunun sağladığı her şeye körü körüne güvenmek yerine İGP tarafından tanımlanan Content-Security-Policy
HTTP üst bilgisi sayesinde güvenilir içerik kaynaklarından oluşan bir izin verilenler listesi oluşturabilir ve tarayıcıya yalnızca bu kaynaklardaki öğeleri yürütme ya da oluşturma talimatı verebilirsiniz. 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.
apis.google.com
'ün geçerli kod yayınlayacağına ve bizim de aynısını yapacağımıza güvendiğimiz için 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? Tahmin edebileceğiniz gibi script-src
, belirli bir sayfa için komut dosyasıyla ilgili ayrıcalıkları 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 apis.google.com
'ten HTTPS üzerinden ve mevcut sayfanın kaynağından indirip yürütür.
Bu politika tanımlandığında tarayıcı, komut dosyasını başka bir kaynaktan yüklemek yerine yalnızca bir hata verir. Zeki bir saldırgan sitenize kod yerleştirmeyi başardığında, beklediği başarıyı elde etmek yerine bir hata mesajıyla karşılaşır.
Politika çok çeşitli kaynaklar için geçerlidir
Komut dosyası kaynakları en belirgin 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önergeleri grubu sağlar. script-src
'ü daha önce gördüğünüz için bu kavramı anlamışsınızdır.
Kaynak yönergelerinin geri kalanını hızlıca inceleyelim. Aşağıdaki liste, 2. seviye itibarıyla yönergelerin durumunu gösterir. 3. seviye bir spesifikasyon yayınlandı ancak büyük tarayıcılarda genel olarak uygulanmıyor.
base-uri
, bir sayfanın<base>
öğesinde görünebilecek URL'leri kısıtlar.child-src
, çalışanların ve yerleşik ç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 devre dışı bırakır.connect-src
, bağlanabileceğiniz kaynaklarını (XHR, WebSockets ve EventSource aracılığıyla) sınırlar.font-src
, web yazı tiplerini sunabilecek 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 dışı kaynaklar için geçerlidir.frame-src
2. düzeyde kullanımdan kaldırıldı ancak 3. düzeyde geri yüklendi. Bu anahtar yoksa yine önceki gibichild-src
değerine 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ını 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
, içerik güvenliği politikası ihlal edildiğinde tarayıcı tarafından raporların gönderileceğ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.
Yönergeler varsayılan olarak geniş kapsamlıdır. Bir yönerge (ör. font-src
) için belirli bir politika ayarlamazsanız bu yönerge varsayılan olarak geçerli kaynak olarak *
'ü belirtmişsiniz gibi davranır (örneğin, yazı tiplerini kısıtlama olmadan herhangi bir yerden yükleyebilirsiniz).
Bir default-src
direktifi belirterek bu varsayılan davranışı geçersiz kılabilirsiniz. Bu yönerge, belirtmediğiniz çoğu yönerge için varsayılan değerleri tanımlar. Bu durum genellikle -src
ile biten tüm yönergeler için geçerlidir. default-src
https://example.com
olarak ayarlanmışsa ve bir font-src
yönergesini belirtmezseniz yazı tiplerini yalnızca https://example.com
'ten 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önergelerde yedek olarak default-src
kullanılmaz. Bu ayarları yapmamanın, her şeye izin vermekle aynı 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 talimatla 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 geçerli olarak doğru şekilde belirtir:
script-src https://host1.com https://host2.com
Örneğin, tüm kaynaklarını bir içerik yayınlama ağı (ör. https://cdn.example.net
) üzerinden yükleyen bir uygulamanız varsa ve çerçevelenmiş içeriğe veya eklentilere ihtiyacınız olmadığını biliyorsanız politikanız aşağıdaki gibi olabilir:
Content-Security-Policy: default-src https://cdn.example.net; child-src 'none'; object-src 'none'
Uygulama ayrıntıları
Web'deki çeşitli eğitim içeriklerinde X-WebKit-CSP
ve X-Content-Security-Policy
üstbilgilerini görürsünüz. Bundan sonra, ön ek içeren bu üstbilgileri yoksaymanız gerekir. Modern tarayıcılar (IE hariç), ön ek eklenmemiş Content-Security-Policy
üstbilgisini destekler. Kullanmanız gereken üst bilgi budur.
Politika, kullandığınız üstbilgiye bakılmaksızın sayfa bazında tanımlanır: Korunmasını istediğiniz her yanıtla birlikte HTTP üst bilgisini 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 bir sayfa grubunda +1 düğmesi varken diğerlerinde olmayabilir. Bu durumda, düğme kodunun yalnızca gerektiğinde 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
, söz konusu ana makinedeki herhangi bir kaynakla (herhangi bir şema, herhangi bir bağlantı noktası) eşleşen) göre tam nitelikli bir URI'ye (https://example.com:443
, yalnızca HTTPS, yalnızca example.com
ve yalnızca 443 bağlantı noktasıyla eşleşen) kadar çeşitlilik gösterecek şekilde belirtebilirsiniz. Joker karakterler kabul edilir ancak yalnızca şema, bağlantı noktası veya ana makine adının en soldaki konumunda kullanılabilir: *://*.example.com:*
, herhangi bir şema ve bağlantı noktası kullanarak example.com
'un tüm alt alan adlarını (ancak example.com
'un kendisini değil) eşleştirir.
Kaynak liste dört anahtar kelime de kabul eder:
'none'
, bekleyebileceğiniz gibi hiçbir şeyle eşleşmiyor.'self'
, mevcut kaynakla eşleşir ancak alt alan adlarıyla eşleşmez.'unsafe-inline'
satır içi JavaScript ve CSS'ye izin verir. (Bu konuyu birazdan daha ayrıntılı bir şekilde ele alacağız.)'unsafe-eval'
,eval
gibi metin-JavaScript mekanizmalarına izin verir. (Bu konuyu da ele alacağız.)
Bu anahtar kelimeler için tek tırnak işareti gerekir. Örneğin, script-src 'self'
(tırnak içinde) geçerli ana makineden JavaScript'in çalıştırılmasına izin verir; script-src self
(tırnak içinde değil) ise "self
" adlı bir sunucudan (mevcut ana makineden değil) JavaScript'e izin verir. Muhtemelen bunu kastetmemiştiniz.
Korumalı alana alma
Konuşulması gereken bir yönerge daha var: sandbox
. Sayfanın yükleyebileceği kaynaklar yerine sayfanın yapabileceği işlemlere kısıtlamalar getirdiği için incelediğimiz diğerlerinden biraz farklıdır. sandbox
yönergesi varsa sayfa, sandbox
özelliğine sahip bir <iframe>
içinde yüklenmiş gibi değerlendirilir. Bu durum, sayfa üzerinde çeşitli etkilere neden olabilir: Sayfayı benzersiz bir kaynağa zorlayabilir ve form göndermeyi engelleyebilir. Bu makalenin kapsamı dışındadır ancak geçerli korumalı alan özellikleri hakkında tüm ayrıntıları HTML5 spesifikasyonunun "Korumalı alan" bölümünde bulabilirsiniz.
Meta etiket
CSP'lerin tercih ettiği teslimat mekanizması bir HTTP başlığıdır. Ancak bir sayfadaki politikayı doğrudan işaretlemede ayarlamak yararlı 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, 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çıktır. Bu, tarayıcıya belirli kaynak gruplarını kabul edilebilir olarak işlemesi ve geri kalanını reddetmesi için net bir talimat verme yöntemidir. Ancak kaynak tabanlı izin verilenler listeleri, XSS saldırılarının oluşturduğu en büyük tehdidi (satır içi komut dosyası ekleme) çözmez.
Bir saldırgan doğrudan kötü amaçlı bir yükü (<script>sendMyDataToEvilDotCom();</script>
) içeren bir komut dosyası etiketi yerleştirebilirse tarayıcı, bu etiketi meşru bir satır içi komut dosyası etiketinden ayırt edemez. CSP, satır içi komut dosyasını tamamen yasaklayarak bu sorunu çözer. Bu, emin olmanın tek yoludur.
Bu yasak yalnızca doğrudan script
etiketlerine yerleştirilmiş komut dosyalarını değil, satır içi etkinlik işleyicileri ve javascript:
URL'lerini de kapsar. script
etiketlerinin içeriğini harici bir dosyaya taşımanız ve javascript:
URL'lerini ve <a ... onclick="[JAVASCRIPT]">
öğelerini uygun addEventListener()
çağrılarıyla değiştirmeniz gerekir. Örneğin, aşağıdakileri şu şekilde yeniden yazabilirsiniz:
<script>
function doAmazingThings() {
alert('YOU AM AMAZING!');
}
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>
şuna benzer bir şeye:
<!-- 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ılmış kodun, CSP ile iyi çalışmanın ötesinde birçok avantajı vardır. CSP'yi kullanmanıza bakılmaksızın, bu kod zaten en iyi uygulamadır. Satır içi JavaScript, yapıyı ve davranışı tam olarak karıştırmanız gerektiği şekilde karıştırır. Dış kaynaklar, tarayıcıların önbelleğe almasını kolaylaştırır, geliştiriciler için daha anlaşılır olur ve derlemeye ve küçültmeye uygundur. Kodu harici kaynaklara taşıma işini yaparsanız daha iyi kodlar yazarsınız.
Satır içi stil de aynı şekilde ele alınır: CSS'nin etkinleştirdiği çeşitli şaşırtıcı derecede akıllı veri sızdırma yöntemlerine karşı koruma sağlamak için hem style
özelliği hem de style
etiketleri harici stil sayfalarında birleştirilmelidir.
Satır içi komut dosyasına ve stile ihtiyacınız varsa script-src
veya style-src
yönergesine izin verilen bir kaynak olarak 'unsafe-inline'
ekleyerek bu özelliği etkinleştirebilirsiniz. Bir tek seferlik rastgele sayı veya karma oluşturma işlemi (aşağıya bakın) de kullanabilirsiniz ancak bunu yapmamanız önerilir.
Satır içi komut dosyasının yasaklanması, CSP'nin sağladığı en büyük güvenlik kazancıdır. Satır içi stilin yasaklanması da uygulamanızın güvenliğini artırır. Tüm kodu satır dışına taşıdıktan sonra işlerin düzgün çalıştığından emin olmak için başlangıçta biraz çaba sarf etmeniz gerekir ancak bu, yapmaya değer bir değişimdir.
Bu seçeneği kesinlikle kullanmanız gerekiyorsa
CSP 2. Katman, şifreleme tek seferlik rastgele sayı (bir kez kullanılan sayı) veya karma oluşturma 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 bir değer kullanmak için komut dosyası etiketinize tek seferlik değer özelliği ekleyin. Değeri, güvenilir kaynaklar listesinde bulunan bir değerle eşleşmelidir. Örneğin:
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
// Some inline code I can't remove yet, but need to asap.
</script>
Ardından, tek seferlik rastgele sayıyı 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 SHA karmasını oluşturup script-src
yönergesine ekleyin.
Örneğin, sayfanızda şunları içerdiğini varsayalım:
<script>
alert('Hello, world.');
</script>
Politikanız şunu içermelidir:
Content-Security-Policy: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng='
Burada dikkat etmeniz gereken birkaç nokta var. sha*-
öneki, karmayı oluşturan algoritmayı belirtir. Yukarıdaki örnekte sha256-
kullanılmaktadır. CSP, sha384-
ve sha512-
'u da destekler. Karma oluşturma işleminde <script>
etiketlerini eklemeyin. Baştaki veya sondaki boşluklar da dahil olmak üzere büyük harf kullanımı ve boşluklar da önemlidir.
SHA karma oluşturma ile ilgili bir Google araması yaptığınızda birçok dilde çözümlere ulaşabilirsiniz. Chrome 40 veya sonraki bir sürümünü kullanarak Geliştirici Araçları'nı açıp sayfanızı yeniden yükleyebilirsiniz. Konsol sekmesinde, satır içi komut dosyalarınızın her biri için doğru sha256 karma değerini içeren hata mesajları yer alır.
Eval da
Bir saldırgan doğrudan komut dosyası ekleyemese bile uygulamanızı kandırarak normalde etkin olmayan metni yürütülebilir JavaScript'e dönüştürüp kendi adına çalıştırabilir. 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 karşı varsayılan yanıtı, bu vektörlerin tümünü tamamen engellemektir.
Bu, uygulama oluşturma şeklinizi birçok açıdan etkiler:
eval
yerine JSON'u yerleşikJSON.parse
aracılığıyla ayrıştırmanız gerekir. Yerleşik 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);
şeklinde yazılmalıdır:
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 kitaplığı, çalışma zamanında şablon oluşturma işlemini hızlandırmak için
new Function()
'ü bolca kullanır. Bu, dinamik programlamanın zekice bir uygulamasıdır ancak kötü amaçlı metinleri değerlendirme riski taşır. Bazı çerçeveler CSP'yi kutudan çıkar çıkmaz destekler veeval
olmadığında güçlü bir ayrıştırıcıya geri döner. AngularJS'nin ng-csp yönergesi buna iyi bir örnektir.
Ancak daha iyi bir seçenek, ön derleme sunan bir şablonlama dili olacaktır (ör. Handlebars). Şablonlarınızı önceden derlemek, kullanıcı deneyimini en hızlı çalışma zamanından bile daha hızlı hale getirebilir ve daha güvenlidir. eval ve metinden JavaScript'e dönüştürme işlevleri uygulamanız için gerekliyse script-src
yönergesine izin verilen bir kaynak olarak 'unsafe-eval'
ekleyerek bunları etkinleştirebilirsiniz ancak bunu yapmanızı kesinlikle önermeyiz. Dize çalıştırma özelliğinin yasaklanması, saldırganların sitenizde yetkisiz kod çalıştırmasını çok daha zor hale getirir.
Raporlama
CSP'nin güvenilmeyen kaynakları istemci tarafında engelleyebilmesi kullanıcılarınız için büyük bir avantajdır. Ancak, kötü amaçlı kod eklemeye izin veren tüm hataları tespit edip ortadan kaldırabilmeniz için sunucuya bir tür bildirim gönderilmesi oldukça yararlı olur. Bu amaçla, tarayıcıyı POST
JSON biçimli ihlal raporlarını report-uri
yönergesinde belirtilen bir konuma göndermesi için talimat 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 rapor, ihlalin gerçekleştiği sayfa (document-uri
), söz konusu sayfanın yönlendiricisi (HTTP başlık alanının aksine anahtarın yanlış yazılmadığını unutmayın), sayfanın politikasını ihlal eden kaynak (blocked-uri
), ihlal edilen belirli yönerge (violated-directive
) ve sayfanın politikanın tamamı (original-policy
) dahil olmak üzere ihlalin nedenini belirlemenize yardımcı olacak birçok bilgi içerir.
Yalnızca Raporlama
CSP'yi yeni kullanmaya başladıysanız kullanıcılarınıza katı bir politika uygulamadan önce uygulamanızın mevcut durumunu değerlendirmeniz önerilir.
Tam bir dağıtımın ilk 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 ihlal raporlarını belirttiğiniz konuma gönderir. Hatta her iki üstbilgiyi de göndererek bir politikayı zorunlu kılarken diğerini de izleyebilirsiniz. Bu, uygulamanızın CSP'sindeki değişikliklerin etkisini değerlendirmenin mükemmel bir yoludur: Yeni bir politika için raporlamayı 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 mevcuttur. Twitter ve Facebook gibi büyük siteler bu başlığı kullanıma sundu (Twitter'ın örnek olayını okumanızı öneririz). Standart, kendi sitelerinizde kullanıma sunmaya hazır.
Uygulamanız için politika oluşturmaya yönelik ilk adım, gerçekten yüklediğiniz kaynakları değerlendirmektir. Uygulamanızdaki öğelerin nasıl bir araya getirildiğini anladığınızı düşündüğünüzde bu şartlara 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. Seviye tabanlı bir politikanız varsa 2. Seviye, bunuchild-src
olarak değiştirmenizi gerektiriyordu. Bu, CSP 3. Seviye'de artık gerekli değildir.Facebook'un Beğen düğmesi için çeşitli uygulama seçenekleri vardır. 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çin birchild-src https://facebook.com
yönergesi gerekir. Facebook'ın sağladığı<iframe>
kodunun varsayılan olarak göreli bir URL (//facebook.com
) yüklediğini unutmayın. Bu değeri, HTTPS'yi açıkça belirtecek şekilde değiştirin:https://facebook.com
. Zorunlu değilse HTTP kullanmanın bir anlamı yoktur.Twitter'ın Tweet düğmesi, her ikisi de
https://platform.twitter.com
adresinde barındırılan bir komut dosyası ve çerçeveye erişimi gerektirir. (Twitter da varsayılan olarak göreli bir URL sağlar. Yerel olarak kopyalayıp yapıştırırken kodu 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ın benzer şartları vardır ve benzer şekilde ele alınabilir.
default-src
'none'
ayarlamanızı ve widget'ların çalışmasını sağlamak için hangi kaynakları etkinleştirmeniz gerektiğini belirlemek üzere konsolunuzu izlemenizi öneririz.
Birden fazla widget eklemek oldukça 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ı: kilitlenme
Bir bankacılık sitesi işlettiğinizi ve yalnızca sizin yazdığınız kaynakların yüklenebildiğinden emin olmak istediğinizi varsayalım. Bu senaryoda, her şeyi engelleyen varsayılan bir politikayla (default-src 'none'
) başlayın ve bu politikadan yola çıkarak ilerleyin.
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, yazı tipi veya ek öğe yoktur. 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 büyük parçalar halinde satır içi komut dosyası ve stille dolu yeniden yazmak, kendisinin yapabileceklerinin çok üzerinde. Aşağıdaki politika geçerli olacaktır:
Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'
https:
, default-src
içinde 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 varsayılan değerin tamamen ü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 iterasyonu olan İçerik Güvenliği Politikası 3. Seviye üzerinde çalışmaya başladı.
Yakında kullanıma sunulacak bu özelliklerle ilgili tartışmaları takip etmek istiyorsanız public-webappsec@ posta listesi arşivlerini gözden geçirin veya tartışmaya katılın.