İçerik Güvenliği Politikası

Mike West
Ali Poşet
Ali Polat

Web'in güvenlik modeli, aynı kaynak politikasına dayanır. https://mybank.com kodu yalnızca https://mybank.com verilerine erişebilmeli ve https://evil.example.com uygulamasının erişimine kesinlikle izin verilmemelidir. Her kaynak web'in geri kalanından izole edilir. Böylece geliştiricilere uygulama geliştirebilecekleri ve oynayabilecekleri güvenli bir korumalı alan sağlanır. Teoride, bu mükemmel bir iş çıkarıyor. Saldırganlar, pratikte sistemi alt etmek için zekice yollar buldular.

Siteler arası komut dosyası çalıştırma (XSS) saldırıları: Örneğin, 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örünen tüm kodun, söz konusu sayfanın güvenlik kaynağının meşru parçası olarak kabul ettiğine güvendiğinden bu büyük bir sorundur. XSS Kısa Açıklamaları, bir saldırganın kötü amaçlı kod ekleyerek bu güveni ihlal etmek için kullanabileceği yöntemlerin eski ancak temsili bir kesişimidir. Bir saldırgan herhangi bir kodu başarıyla yerleştirirse oyun büyük ölçüde sona erer: Kullanıcı oturumu verilerinin güvenliği ihlal edilir ve gizli tutulması gereken bilgiler Bad Guys'a çalınır. Bunu mümkünse engellemek isteriz.

Bu genel bakış, modern tarayıcılarda XSS saldırılarının riskini ve etkisini önemli ölçüde azaltabilecek bir savunmayı vurgular: İçerik Güvenliği Politikası (CSP).

Özet

  • İzin verilen ve verilmeyen içerikleri müşteriye bildirmek için izin verilenler listelerini kullanın.
  • Hangi yönergelerin kullanılabileceğini öğrenin.
  • Kullandıkları anahtar kelimeleri öğrenme.
  • Satır içi kod ve eval() zararlı olarak kabul edilir.
  • Politika ihlallerini zorunlu kılmadan önce sunucunuza bildirin.

Kaynak izin verilenler listeleri

XSS saldırılarından kaynaklanan sorun, tarayıcının, uygulamanızın bir parçası olan komut dosyası ile üçüncü bir tarafın kötü niyetli bir şekilde eklediği komut dosyasını birbirinden ayırt edememesidir. Örneğin, bu sayfanın alt kısmındaki Google +1 düğmesi, https://apis.google.com/js/plusone.js kodunu bu sayfanın kaynak bağlamında yükler ve yürütür. Bu koda güveniyoruz, ancak tarayıcının apis.google.com kaynaklı kodun harika olduğunu kendi başına anlamasını bekleyemiyoruz ancak apis.evil.example.com kaynaklı kod muhtemelen öyle değil. Tarayıcı, kaynağından bağımsız olarak sayfanın istediği kodu sorunsuz bir şekilde indirir ve yürütür.

Sunucunun yayınladığı her şeye körü körüne güvenmek yerine CSP, Content-Security-Policy HTTP üst bilgisini tanımlar. Bu üst bilgi, güvenilir içerik kaynaklarının izin verilenler listesini oluşturmanıza olanak tanır ve tarayıcıya yalnızca bu kaynaklardan gelen kaynakları yürütmesini veya oluşturmasını bildirir. Bir saldırgan, komut dosyasının ekleneceği bir delik bulsa bile komut dosyası izin verilenler listesiyle eşleşmez ve bu nedenle yürütülmez.

Geçerli kod sunma konusunda apis.google.com uygulamasına ve aynısını yapma konusunda kendimize de güvendiğimizden, komut dosyasının yalnızca şu iki kaynaktan birinden geldiği zaman 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 edeceğiniz gibi script-src, belirli bir sayfa için komut dosyasıyla ilgili bir dizi ayrıcalığı kontrol eden bir yönergedir. 'self' öğesini geçerli bir komut dosyası kaynağı ve https://apis.google.com başka bir komut dosyası kaynağı olarak belirledik. Tarayıcı, JavaScript'i apis.google.com üzerinden hem HTTPS üzerinden hem de geçerli sayfanın kaynağından sorunsuz bir şekilde indirip çalıştırır.

Konsol hatası: "http://evil.example.com/evil.js" komut dosyası, şu İçerik Güvenliği Politikası yönergesini ihlal ettiği için reddedildi: script-src "self" https://apis.google.com

Bu politika tanımlandığında, tarayıcı başka herhangi 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ı yerine doğrudan bir hata mesajıyla karşılaşır.

Politika, çok çeşitli kaynaklar için geçerlidir

Komut dosyası kaynakları en bariz güvenlik riskleridir. Bununla birlikte CSP, bir sayfanın yüklemesine izin verilen kaynaklar üzerinde oldukça ayrıntılı kontrol sağlayan zengin bir politika yönergeleri kümesi sunar. script-src oyununu zaten görmüşsünüzdür, dolayısıyla konsept net olmalıdır.

Geri kalan kaynak yönergelerine hızlıca göz atalım. Aşağıdaki liste, 2. seviye itibarıyla yönergelerin durumunu göstermektedir. 3. düzey spesifikasyon yayınlanmış olsa da başlıca tarayıcılarda büyük ölçüde uygulanmamış.

  • base-uri, bir sayfanın <base> öğesinde görünebilecek URL'leri kısıtlar.
  • child-src, çalışanların URL'lerini ve yerleştirilmiş çerçeve içeriklerini listeler. Örneğin: child-src https://youtube.com, diğer kaynaklardan değil YouTube'dan video yerleştirmeyi etkinleştirir.
  • connect-src, bağlanabileceğiniz kaynakları sınırlandırır (XHR, WebSockets ve EventSource aracılığıyla).
  • font-src, web yazı tiplerini sunabilecek kaynakları belirtir. Google'ın web yazı tipleri font-src https://themes.googleusercontent.com ile etkinleştirilebilir.
  • form-action, <form> etiketten 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 uygulaması 2. seviyede kullanımdan kaldırılmış ancak 3. seviyede geri yüklenmiştir. Sunulmadığı takdirde, daha önce olduğu gibi child-src değerine geri döner.
  • img-src, resimlerin 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 sağlar.
  • plugin-types bir sayfanın çağırabileceği eklenti türlerini sınırlandırır.
  • report-uri, 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 öğesinin stil sayfalarının eşdeğeridir.
  • upgrade-insecure-requests, kullanıcı aracılarına URL şemalarını yeniden yazarak HTTP'yi HTTPS'ye değiştirmelerini bildirir. 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 tarihinden itibaren bu yönerge sınırlı şekilde uygulanmaktadır.

Varsayılan olarak yönergeler geniş kapsamlıdır. font-src gibi bir yönerge için belirli bir politika belirlemezseniz söz konusu yönerge, geçerli kaynak olarak * politikasını belirlemiş olduğunuz gibi varsayılan olarak davranır (örneğin, yazı tiplerini kısıtlama olmaksızın her yerden yükleyebilirsiniz).

Bir default-src yönergesi belirterek bu varsayılan davranışı geçersiz kılabilirsiniz. Bu yönerge, belirtmediğiniz ç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 kaynağından yazı tipleri yükleyebilirsiniz. Başka hiçbir yerden yükleyemezsiniz. Önceki örneklerimizde yalnızca script-src değerini belirtmiştik. Bu, resimler, yazı tipleri vb. her kaynaktan yüklenebileceği anlamına gelir.

Aşağıdaki yönergeler, yedek olarak default-src kullanmaz. Unutmayın, bunları ayarlamamak her şeye izin vermekle aynı şeydir.

  • base-uri
  • form-action
  • frame-ancestors
  • plugin-types
  • report-uri
  • sandbox

Bu direktiflerden istediğiniz kadar kullanabilir ve her birini HTTP üst bilgisinde listeleyerek yönergeleri noktalı virgülle ayırarak kullanabilirsiniz. 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 yazdıysanız ikinci yönerge yok sayılır. Aşağıdakine benzer bir şey, 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 (örneğin, https://cdn.example.net) yükleyen bir uygulamanız varsa ve çerçevelenmiş içeriğe veya eklentiye 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 böyle, bu ön ekli başlıkları yoksaymalısınız. Modern tarayıcılar (IE hariç) öneksiz Content-Security-Policy başlığını destekler. Bu, kullanmanız gereken başlıktır.

Politika, kullandığınız başlıktan bağımsız olarak sayfa bazında tanımlanır: Korunduğundan emin olmak istediğiniz her yanıtla birlikte HTTP üst bilgisini göndermeniz gerekir. Bu yöntem, politikaları belirli ihtiyaçlara göre belirli sayfalar için ince ayar yapmanıza olanak sağladığından büyük esneklik sağlar. Sitenizdeki sayfalardan bir tanesinde +1 düğmesi varken bazılarında yoktur: 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ından (bu ana makinedeki herhangi bir kaynakla eşleşen example.com) tam nitelikli bir URI'ye (https://example.com:443, yalnızca HTTPS, yalnızca example.com ve yalnızca bağlantı noktası 443 ile eşleşen https://example.com:443) kadar bir aralıkta belirtebilirsiniz. Joker karakterler kabul edilir ancak yalnızca şema, bağlantı noktası veya ana makine adının en sol konumunda bulunur: *://*.example.com:*, herhangi bir bağlantı noktasında herhangi bir şema kullanarak example.com kapsamındaki tüm alt alan adlarıyla eşleşir (example.com ile değil).

Kaynak liste dört anahtar kelime de kabul eder:

  • Tahmin edebileceğiniz gibi, 'none' hiçbir şeyle eşleşmiyor.
  • 'self' geçerli 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 ayrıntılı olarak 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şaretleriyle) mevcut ana makineden JavaScript'in yürütülmesini yetkilendirir; script-src self (tırnak işareti olmadan), "self" adlı (ve geçerli ana makineden değil) bir sunucudan JavaScript'e izin verir. Muhtemelen kastettiğiniz bu değildir.

Korumalı alana alma

Bahsetmeye değer bir yönerge daha var: sandbox. İncelediğimiz diğer sayfalardan biraz farklıdır çünkü sayfanın yüklenebileceği kaynaklar yerine sayfanın yapabileceği işlemler üzerinde kısıtlamalar vardır. sandbox yönergesi varsa sayfa, sandbox özelliğine sahip bir <iframe> içinde yüklenmiş gibi değerlendirilir. Bunun sayfada çok çeşitli etkileri olabilir: Sayfayı benzersiz bir kaynağa zorlamak ve form gönderimini önlemek gibi işlemler. Konu, 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

CSP'lerin tercih ettiği teslim mekanizması bir HTTP başlığıdır. Bununla birlikte, bir sayfada doğrudan işaretlemeyi kullanarak politika belirlemek faydalı olabilir. Bunu http-equiv özellikli 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'"
/>

frame-ancestors, report-uri veya sandbox için kullanılamaz.

Satır içi kod zararlı olarak kabul edilir

CSP'nin izin verilenler listesi kaynaklarını temel aldığı açıkça belirtilmelidir. 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. Ancak kaynak tabanlı izin verilenler listeleri, XSS saldırılarının oluşturduğu en büyük tehdidi, yani satır içi komut dosyası yerleştirmeyi ortadan kaldırmaz. Bir saldırgan, doğrudan kötü amaçlı yük (<script>sendMyDataToEvilDotCom();</script>) içeren bir komut dosyası etiketi yerleştirebilirse tarayıcının bunu geçerli bir satır içi komut dosyası etiketinden ayırt etmesini sağlayacak bir mekanizması yoktur. CSP bu sorunu satır içi komut dosyasını tamamen yasaklayarak çözmektedir: Emin olmanın tek yolu budur.

Bu yasak, doğrudan script etiketlerine yerleştirilmiş komut dosyalarını değil, satır içi etkinlik işleyicileri ve javascript: URL'lerini de içerir. script etiketlerinin içeriğini harici bir dosyaya taşımanız ve javascript: URL'ler ile <a ... onclick="[JAVASCRIPT]">'yi uygun addEventListener() çağrılarıyla değiştirmeniz gerekir. Örneğin, aşağıdakileri şuradan yeniden yazabilirsiniz:

<script>
  function doAmazingThings() {
    alert('YOU AM AMAZING!');
  }
</script>
<button onclick="doAmazingThings();">Am I amazing?</button>

ve şunun gibi bir şey olsun:

<!-- 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 kod, CSP ile iyi çalışmasının ötesinde bir dizi avantaja sahiptir; CSP ne olursa olsun bu zaten en iyi uygulamadır. Satır içi JavaScript, yapı ve davranışı tam olarak bunu yapmamanız gereken şekilde karıştırır. Harici kaynaklar, tarayıcılar için daha kolay önbelleğe alınır, geliştiriciler için daha anlaşılır ve derleme ile sadeleştirmeye elverişlidir. Kodu harici kaynaklara taşırsanız daha iyi kod yazarsınız.

Satır içi stil aynı şekilde ele alınır: CSS'nin etkinleştirdiği çeşitli ş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ştirilmelidir.

Satır içi komut dosyasına ve stile sahip olmanız gerekiyorsa 'unsafe-inline' öğesini script-src veya style-src yönergesinde izin verilen kaynak olarak ekleyerek etkinleştirebilirsiniz. Ayrıca tek seferlik rastgele bir sayı veya karma (aşağıya bakın) kullanabilirsiniz, ancak bunu yapamazsınız. Satır içi komut dosyasının yasaklanması CSP'nin sağladığı en büyük güvenlik avantajıdır ve satır içi stilin yasaklanması da uygulamanızı sertleştirir. Tüm kodları satır dışına taşıdıktan sonra her şeyin doğru bir şekilde çalışmasını sağlamak için önceden biraz çaba sarf etmek gerekir, ancak bu, iyi bir ödün vermeye değer.

Mutlaka kullanmanız gerekiyorsa

CSP Düzey 2, şifreleme 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 yöntem zahmetli görünse de ufak tefek işlere yarar.

Tek seferlik rastgele sayı kullanmak için komut dosyası etiketinize nonce özelliği verin. Değeri, güvenilir kaynaklar listesindeki bir değerle 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 sayıyı nonce- anahtar kelimesine eklenen script-src yönergesine ekleyin.

Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'

Her sayfa isteği için nonce'ların yeniden oluşturulması ve tahmin edilemez olması gerektiğini unutmayın.

Karmalar da aşağı yukarı aynı şekilde işler. Komut dosyası etiketine kod eklemek yerine, komut dosyasının SHA karmasını oluşturun ve bunu script-src yönergesine ekleyin. Örneğin, sayfanızda aşağıdakilerin bulunduğunu varsayalım:

<script>
  alert('Hello, world.');
</script>

Politikanız şunları içerir:

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-'yi de destekler. Karma oluşturma işlemini oluştururken <script> etiketlerini eklemeyin. Ayrıca, baştaki veya sondaki boşluklar dahil olmak üzere büyük harf kullanımı ve boşluk kullanımı da önemlidir.

SHA karmaları oluşturmayla ilgili Google aramaları sizi çeşitli dillerde çö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 sekmesinde, satır içi komut dosyalarınızın her biri için doğru sha256 karmasına sahip hata mesajları bulunur.

Eval da

Bir saldırgan doğrudan komut dosyası ekleyemese bile, uygulamanızı kandırarak diğer türlü durağan metni yürütülebilir JavaScript'e dönüştürebilir ve bu metni kendi adına yürütebilir. eval(), new Function() , setTimeout([string], ...) ve setInterval([string], ...), yerleştirilen metnin beklenmedik bir şekilde kötü amaçlı bir dosya yürütmesine yol açabilecek vektörlerdir. CSP'nin bu riske varsayılan yanıtı, tüm bu vektörleri tamamen engellemektir.

Bunun, uygulama derleme yönteminiz üzerinde birkaçdan fazla etkisi vardır:

  • eval kullanmak yerine JSON'u yerleşik JSON.parse aracılığıyla ayrıştırmalısınız. Yerel JSON işlemleri, IE8'den beri her tarayıcıda kullanılabilir ve tamamen güvenlidir.
  • Şu anda yaptığınız setTimeout veya setInterval ç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 daha iyi 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şturmayı hızlandırmak için new Function()'yi serbest bir şekilde kullanır. Bu, dinamik programlama için harika bir uygulama olsa da kötü amaçlı metinleri değerlendirme riskiyle karşı karşıyadır. Bazı çerçeveler, CSP'yi kullanıma hazır şekilde destekler ve eval olmadığında güçlü bir ayrıştırıcıya dönüşür. AngularJS'nin ng-csp yönergesi bunun için iyi bir örnektir.

Ancak, önceden derleme olanağı sunan bir şablon dili kullanmak daha iyi bir tercihtir (örneğin, Gidon çubukları). Şablonlarınızı önceden derlemek, kullanıcı deneyimini en hızlı çalışma zamanı uygulamasından daha hızlı hale getirebilir ve aynı zamanda daha güvenlidir. Değerlendirme ve JavaScript'e giden metin türleri uygulamanız için gerekliyse script-src yönergesinde 'unsafe-eval' adresini izin verilen kaynak olarak ekleyerek bunları etkinleştirebilirsiniz, ancak bunu yapmanızı kesinlikle önermiyoruz. Dize yürütme özelliğinin yasaklanması, 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 engelleyebilme özelliği kullanıcılarınız için çok büyük bir kazanımdır. Ancak sunucuya kötü amaçlı yerleştirmeye izin veren hataları tespit edip önleyebilmeniz için sunucuya bir tür bildirim gönderilmesi çok faydalı olacaktır. Bu amaçla, tarayıcıya report-uri yönergesinde belirtilen bir konumla ilgili POST JSON biçimli ihlal raporları gönderme 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, ihlalin meydana geldiği sayfa (document-uri), sayfayı yönlendiren (HTTP başlık alanından farklı olarak, anahtarın yanlış yazılmadığını olmadığını, sayfanın politikasını ihlal eden kaynak (blocked-uri), ihlal ettiği belirli yönergeyi (violated-directive) ve sayfanın tüm politikasını (original-policy) içerir. Bu bilgiler arasında, ihlalin nedenini tespit etmenize yardımcı olacak bol miktarda bilgi yer alır.

Yalnızca Rapor

CSP'yi kullanmaya yeni başlıyorsanız kullanıcılarınıza acımasız bir politika sunmadan önce başvurunuzun mevcut durumunu değerlendirmeniz önerilir. Eksiksiz bir dağıtıma adım adım atmak için tarayıcıdan bir politikayı izleyip, 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 bir politikayı izlerken diğerini uygulayarak her iki üst bilgiyi de gönderebilirsiniz. Bu, uygulamanızın İGP'deki değişikliklerin etkisini değerlendirmenin çok etkili bir yoludur: Yeni bir politika için raporlamayı açın, ihlal raporlarını izleyin ve ortaya çıkan hataları düzeltin. Değişikliğin etkisinden memnun olduğunuzda yeni politikayı uygulamaya başlayın.

Gerçek Dünyadan Kullanım

CSP 1; Chrome, Safari ve Firefox'ta oldukça kullanılabilir, ancak IE 10'da son derece sınırlı şekilde desteklenmektedir. Özellikleri caniuse.com adresinde görüntüleyebilirsiniz. CSP Düzey 2, Chrome'da 40 sürümünden itibaren kullanılmaktadır. Twitter ve Facebook gibi büyük siteler başlığı dağıtmıştır (Twitter'ın örnek olayı okunmaya değer). Bu standart, kendi sitelerinizde dağıtmaya başlamanız için artık çok hazır.

Uygulamanız için politika oluşturmanın ilk adımı, yüklediğiniz kaynakları değerlendirmektir. Uygulamanızda her şeyin nasıl derlendiğine hakim olduğunuzu düşündüğünüzde bu gereksinimlere uygun bir politika oluşturun. Yaygın kullanım alanlarından birkaçına göz atalım ve CSP'nin koruyucu sınırları içinde bunları 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 ve https://plusone.google.com kaynağından bir <iframe> yerleştirir. Düğmeyi yerleştirmek için her iki kaynağı da içeren bir politikaya ihtiyacınız vardır. Minimum politika script-src https://apis.google.com; child-src https://plusone.google.com olacaktır. Ayrıca, Google'ın sağladığı JavaScript snippet'inin harici bir JavaScript dosyasına çekildiğinden emin olmanız gerekir. Seviye 1'e dayalı bir frame-src kullanan politikanız varsa 2. Seviyeyi child-src olarak değiştirmenizi gerektiriyordu. CSP Düzey 3'te artık buna gerek yoktur.

  • Facebook'un Beğen düğmesi bir dizi uygulama seçeneğine sahiptir. Sitenizin geri kalanından 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 bir child-src https://facebook.com yönergesi gerekir. Varsayılan olarak Facebook'un sağladığı <iframe> kodunun //facebook.com göreli URL yüklediğini unutmayın. Bunu açık bir şekilde HTTPS'yi belirtecek şekilde değiştirin: https://facebook.com. Mecbur kalmazsanız HTTP kullanmanız da 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şim sağlar. (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ürece her şey script-src https://platform.twitter.com; child-src https://platform.twitter.com olacak.

  • Diğer platformların gereksinimleri benzerdir ve benzer şekilde ele alınabilir. 'none' için bir default-src ayarlamanız ve widget'ların çalışması 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 unutmadan politika yönergelerini birleştirmeniz yeterlidir. Sosyal medya widget'larının üçünü de isterseniz politika şöyle görünür:

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 gizlilik

Bir an için bir bankacılık sitesi yönettiğinizi ve yalnızca sizin yazdığınız kaynakların yüklendiğinden emin olmak istediğinizi varsayalım. Bu senaryoda, kesinlikle her şeyi (default-src 'none') engelleyen varsayılan bir politikayla başlayın ve o noktadan devam edin.

Bankanın tüm resimleri, stili ve komut dosyasını https://cdn.mybank.net adresindeki CDN'den yüklediğini ve çeşitli veri parçalarını aşağı çekmek için XHR aracılığıyla https://api.mybank.com/'ye bağlandığını varsayalım. Çerçeveler, yalnızca sitenin yerel sayfaları için kullanılır (üçüncü taraf kaynakları kullanılmaz). Sitede Flash, yazı tipi veya ekstralar 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

Bir evlilik tartışma forumu yöneticisi, tüm kaynakların yalnızca güvenli kanallar aracılığıyla yüklendiğinden emin olmak istiyor ancak çok fazla kod yazmadığından satır içi komut dosyası ve stille dolu üçüncü taraf forum yazılımının büyük parçalarını yeniden yazmak mümkün değil. Aşağıdaki politika geçerli olur:

Content-Security-Policy: default-src https:; script-src https: 'unsafe-inline'; style-src https: 'unsafe-inline'

https:, default-src politikasında belirtilse bile, komut dosyası ve stil yönergeleri bu kaynağı otomatik olarak devralmaz. Her yönerge, söz konusu kaynak türüne ait varsayılan değerin tamamen üzerine yazılır.

Gelecek

İçerik Güvenliği Politikası Düzey 2, bir Aday Önerisi'dir. W3C'nin Web Uygulaması Güvenliği Çalışma Grubu, spesifikasyonun bir sonraki yinelemesi olan İçerik Güvenliği Politikası Düzeyi 3 üzerinde çalışmaya çoktan başladı.

Yeni kullanıma sunulacak bu özelliklerle ilgili tartışmak isterseniz public-webappsec@ posta listesi arşivlerine göz atın veya kendiniz de katılın.

Geri bildirim