İçerik Güvenliği Politikası nasıl çalışır?


248

Geliştirici konsolunda bir sürü hata alıyorum:

Bir dizeyi değerlendirmeyi reddetti

Aşağıdaki İçerik Güvenliği İlkesi yönergesini ihlal ettiği için satır içi komut dosyasını yürütmeyi reddetti

Komut dosyasını yüklemeyi reddetti

Stil sayfasını yüklemeyi reddetti

Bütün bunlar ne hakkında? İçerik Güvenliği Politikası nasıl çalışır? Content-Security-PolicyHTTP üstbilgisini nasıl kullanırım ?

Özellikle, nasıl ...

  1. ... birden fazla kaynağa izin verilsin mi?
  2. ... farklı direktifler mi kullanıyorsunuz?
  3. ... birden fazla yönerge mi kullanıyorsunuz?
  4. ... portları mı tutuyorsunuz?
  5. ... farklı protokolleri mi kullanıyorsunuz?
  6. ... file://protokole izin verilsin mi?
  7. ... satır içi stiller, komut dosyaları ve etiketler kullanın <style>ve <script>?
  8. ... izin ver eval()?

Ve sonunda:

  1. Tam olarak ne anlama 'self'geliyor?

Yanıtlar:


557

Content-Security-PolicyMeta etiketi, riskini azaltmak için izin verir XSS kaynakları başka yerlerden yükleme verilerinden tarayıcılar engelleyen, yüklenebilir nerede tanımlamak için izin vererek saldırıları. Bu, bir saldırganın sitenize kötü amaçlı kod eklemesini zorlaştırır.

Kafamı neden birbiri ardına CSP hataları aldığımı anlamaya çalışan bir tuğla duvara çarptım ve nasıl çalıştığına dair kesin ve net talimatlar yoktu. Bu yüzden , CSP'nin bazı noktalarını kısaca açıklamaya çalışıyorum , çoğunlukla çözmek zor bulduğum şeylere odaklanıyoruz.

Kısacası, her örnekte tam etiketi yazmayacağım. Bunun yerine sadececontent özelliği , bu yüzden bir örnek şu content="default-src 'self'"anlama gelir:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

1. Birden fazla kaynağa nasıl izin verilir?

Bir yönergeden sonra kaynaklarınızı boşlukla ayrılmış bir liste olarak listeleyebilirsiniz:

content="default-src 'self' https://example.com/js/"

Özel parametreler dışında tırnak işaretleri bulunmadığını unutmayın gibi olanlar 'self'. Ayrıca, :direktiften sonra iki nokta üst üste ( ) işareti yoktur . Sadece yönerge, sonra boşlukla ayrılmış bir parametre listesi.

Belirtilen parametrelerin altındaki her şeye dolaylı olarak izin verilir. Bu, yukarıdaki örnekte bunların geçerli kaynaklar olacağı anlamına gelir:

https://example.com/js/file.js
https://example.com/js/subdir/anotherfile.js

Ancak bunlar geçerli olmaz:

http://example.com/js/file.js
^^^^ wrong protocol

https://example.com/file.js
                   ^^ above the specified path

2. Farklı direktifler nasıl kullanılır, her biri ne yapar?

En yaygın direktifler:

  • default-src javascript, resimler, CSS, yazı tipleri, AJAX istekleri vb. yüklemek için varsayılan politika
  • script-src javascript dosyaları için geçerli kaynakları tanımlar
  • style-src css dosyaları için geçerli kaynakları tanımlar
  • img-src görüntüler için geçerli kaynakları tanımlar
  • connect-srcXMLHttpRequest (AJAX), WebSockets veya EventSource için geçerli hedefleri tanımlar. Burada izin verilmeyen bir ana bilgisayara bağlantı denemesi yapılırsa tarayıcı bir 400hata taklit eder

Başkaları da var, ama bunlar en çok ihtiyacınız olanlar.

3. Birden çok direktif nasıl kullanılır?

Noktalı virgül ( ;) ile sonlandırarak tek bir meta etiket içindeki tüm yönergelerinizi tanımlarsınız :

content="default-src 'self' https://example.com/js/; style-src 'self'"

4. liman nasıl ele alınır?

Varsayılan bağlantı noktaları dışındaki her şeye izin verilen alan adından sonra bağlantı noktası numarası veya yıldız işareti eklenerek açıkça izin verilmelidir:

content="default-src 'self' https://ajax.googleapis.com http://example.com:123/free/stuff/"

Yukarıdaki sonuç:

https://ajax.googleapis.com:123
                           ^^^^ Not ok, wrong port

https://ajax.googleapis.com - OK

http://example.com/free/stuff/file.js
                 ^^ Not ok, only the port 123 is allowed

http://example.com:123/free/stuff/file.js - OK

Bahsettiğim gibi, tüm bağlantı noktalarına açıkça izin vermek için bir yıldız işareti de kullanabilirsiniz:

content="default-src example.com:*"

5. Nasıl farklı protokolleri işlemek için?

Varsayılan olarak, yalnızca standart protokollere izin verilir. Örneğin, WebSockets'e ws://izin vermek için açıkça izin vermeniz gerekir:

content="default-src 'self'; connect-src ws:; style-src 'self'"
                                         ^^^ web sockets are now allowed on all domains and ports

6. Dosya protokolüne nasıl izin verilir file://?

Eğer böyle tanımlamaya çalışırsanız işe yaramaz. Bunun yerine, şu filesystemparametre ile izin verirsiniz :

content="default-src filesystem"

7. Satır içi komut dosyaları ve stil tanımlamaları nasıl kullanılır?

Açıkça izin verilmedikçe, satır içi stil tanımlarını, <script>etiketlerin içindeki kodu veya gibi etiket özelliklerinde kullanamazsınız onclick. Onlara şöyle izin veriyorsunuz:

content="script-src 'unsafe-inline'; style-src 'unsafe-inline'"

Ayrıca satır içi, base64 kodlu resimlere açıkça izin vermeniz gerekir:

content="img-src data:"

8. Nasıl izin verilir eval()?

Eminim birçok insan bunu söylemez. Bu insanlar yanlış olur. Elbette, eval ile sitenizin güvenliğine kesinlikle büyük delikler açabilirsiniz, ancak mükemmel geçerli kullanım durumlarına sahiptir. Sadece kullanmak konusunda akıllı olmalısınız. Buna izin veriyorsunuz:

content="script-src 'unsafe-eval'"

9. Tam olarak ne anlama 'self'geliyor?

Alabilirsin 'self' aynı ana bilgisayarda ortalama localhost, yerel dosya sisteminde veya bir şey. Bunların hiçbiri anlamına gelmez. İçerik politikasının tanımlandığı dosyayla aynı şemaya (protokol), aynı ana bilgisayara ve aynı bağlantı noktasına sahip olan kaynaklar anlamına gelir. Sitenizi HTTP üzerinden mi sunuyorsunuz? Açıkça tanımlamazsanız, sizin için https yok.

Kullandım 'self' genellikle dahil etmek mantıklı gibi çoğu örneklerde, ancak zorunlu hiçbir şekilde bu. İhtiyacınız yoksa dışarıda bırakın.

Ama bir dakika bekle! Sadece onunla kullanıp bitiremez miyim content="default-src *"?

Hayır. Belirgin güvenlik açıklarına ek olarak, bu beklediğiniz gibi çalışmaz. Bazı dokümanlar her şeye izin verdiğini iddia etse de , bu doğru değil. Satır içi veya geliştirmelere izin vermez, bu nedenle sitenizi gerçekten daha savunmasız hale getirmek için şunu kullanırsınız:

content="default-src * 'unsafe-inline' 'unsafe-eval'"

... ama güvenmeyeceğine inanıyorum.

Daha fazla okuma:

http://content-security-policy.com

http://en.wikipedia.org/wiki/Content_Security_Policy


6
Harika gönderi. Bir şey: birden fazla direktif belirtildiğinde ne olacağı belli değil; örnek 3'teki style-src ayarları default-src'den önceliklidir? vs ...
track0 03.03.2015

30
Yani, izin herşey herşey herşey içeriği olurdudefault-src *; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'; img-src * data: 'unsafe-inline'; connect-src * 'unsafe-inline'; frame-src *;
Arnold ROA

8
content="default-src * 'unsafe-inline' 'unsafe-eval'"Bazı Açısal uygulamaların çalışması için gerekli olduğunu bilmek önemlidir .
flanger001

2
@ Mahesh Bu "blog" SO'dan kopyalanan yayınlarla doludur. Pek çok SO kullanıcısının bilinmeyen bir blogcudan içerik kopyalaması pek olası görünmüyor - Yapmadığımı biliyorum.
Schlaus

2
connect-srcYollar ve yollar hakkında kısa not : Bütün bir alt yol eklemek istiyorsanız, eğik çizgiler zorunludur. Örn: http://foo.com/files/bar.txtkaynak ise dosya engellenir http://foo.com/files, ancak şu durumda sunulurhttp://foo.com/files/
Griddo

15

APACHE2 MOD_HEADERS

Ayrıca Apache2 mod_headers'ı da etkinleştirebilirsiniz, Fedora'da, varsayılan olarak zaten etkindir, Ubuntu / Debian kullanıyorsanız, bu şekilde etkinleştirin:

# First enable headers module for Apache2, 
# then restart the Apache2 service   
a2enmod headers
apache2 -k graceful

Ubuntu / Debian'da dosyadaki başlıkları yapılandırabilirsiniz /etc/apache2/conf-enabled/security.conf

#
# Setting this header will prevent MSIE from interpreting files as something
# else than declared by the content type in the HTTP headers.
# Requires mod_headers to be enabled.
# 
#Header set X-Content-Type-Options: "nosniff"

#
# Setting this header will prevent other sites from embedding pages from this
# site as frames. This defends against clickjacking attacks.
# Requires mod_headers to be enabled.
#
Header always set X-Frame-Options: "sameorigin"
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
Header always set X-Permitted-Cross-Domain-Policies "master-only"
Header always set Cache-Control "no-cache, no-store, must-revalidate"
Header always set Pragma "no-cache"
Header always set Expires "-1"
Header always set Content-Security-Policy: "default-src 'none';"
Header always set Content-Security-Policy: "script-src 'self' www.google-analytics.com adserver.example.com www.example.com;"
Header always set Content-Security-Policy: "style-src 'self' www.example.com;"

Not: Bu dosyanın alt kısmıdır, yalnızca son 3 giriş CSP ayarlarıdır.

İlk parametre yönerge, ikincisi beyaz listeye alınacak kaynaklardır. Google analizlerini ve sahip olabileceğiniz bir reklam sunucusunu ekledim. Ayrıca, Apache2'de yapılandırılmış örneğin www.example.com ve example.com gibi takma adlarınız varsa, bunları beyaz listeye de eklemeniz gerektiğini buldum.

Satır içi kod zararlı olarak kabul edilir, bundan kaçınmalısınız. Tüm javascripts ve css dosyalarını ayrı dosyalara kopyalayın ve beyaz listeye ekleyin.

Siz oradayken diğer başlık ayarlarına göz atabilir ve mod_security'yi yükleyebilirsiniz.

Daha fazla okuma:

https://developers.google.com/web/fundamentals/security/csp/

https://www.w3.org/TR/CSP/


2
Paylaşılan ana makinemde Apache yapılandırmalarını düzenleme yeteneğim olmadığından, aynı yönergeleri .htaccess dosyama ekleyebildim. Bu ayarları yapmak için report-uri.io/home/tools adresinde mükemmel araçlar buldum .
Michael McGinnis

Tomcat 7 ile bunu çözmek için herhangi bir yolu var mı? Filtreler eklemeyi denedim ve işe yaramadı.
Elshan

0

Diğerleriyle aynı şekilde çalışan font-src'yi unutmayın, ancak başka kaynaklardan yüklenen fontlar kullanıyorsanız - meta etikete eklediğinizden emin olun

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.