Bagaimana cara kerja Kebijakan Keamanan Konten?

248

Saya mendapat banyak kesalahan di konsol pengembang:

Menolak untuk mengevaluasi string

Menolak untuk menjalankan skrip inline karena melanggar arahan Kebijakan Keamanan Konten berikut

Menolak memuat skrip

Menolak memuat stylesheet

Tentang apa semua ini? Bagaimana cara kerja Kebijakan Keamanan Konten? Bagaimana cara menggunakan Content-Security-Policyheader HTTP?

Secara khusus, bagaimana ...

  1. ... izinkan beberapa sumber?
  2. ... menggunakan arahan yang berbeda?
  3. ... gunakan beberapa arahan?
  4. ... menangani port?
  5. ... menangani protokol yang berbeda?
  6. ... izinkan file://protokol?
  7. ... menggunakan gaya inline, skrip, dan tag <style>dan <script>?
  8. ... ijinkan eval()?

Dan akhirnya:

  1. Apa sebenarnya 'self'artinya?
Schlaus
sumber

Jawaban:

557

The Content-Security-Policymeta-tag memungkinkan Anda untuk mengurangi risiko XSS serangan dengan memungkinkan Anda untuk menentukan di mana sumber daya dapat diambil dari, mencegah browser dari loading data dari lokasi lain. Ini mempersulit penyerang untuk menyuntikkan kode berbahaya ke situs Anda.

Saya membenturkan kepala ke dinding batu bata untuk mencari tahu mengapa saya mendapatkan kesalahan CSP satu demi satu, dan sepertinya tidak ada petunjuk yang jelas dan jelas tentang bagaimana cara kerjanya. Jadi, inilah upaya saya untuk menjelaskan beberapa poin CSP secara singkat, sebagian besar berkonsentrasi pada hal-hal yang sulit saya pecahkan.

Untuk singkatnya saya tidak akan menulis tag lengkap di setiap sampel. Alih-alih, saya hanya akan menunjukkan contentproperti, jadi contoh yang mengatakan content="default-src 'self'"artinya:

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

1. Bagaimana cara mengizinkan beberapa sumber?

Anda dapat dengan mudah mendaftarkan sumber-sumber Anda setelah arahan sebagai daftar yang dipisahkan oleh ruang:

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

Perhatikan bahwa tidak ada tanda kutip di sekitar parameter selain yang khusus , seperti 'self'. Juga, tidak ada titik dua ( :) setelah arahan. Hanya arahan, lalu daftar parameter yang dipisahkan ruang.

Segala sesuatu di bawah parameter yang ditentukan diizinkan secara implisit. Itu berarti bahwa dalam contoh di atas ini akan menjadi sumber yang valid:

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

Namun, ini tidak valid:

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

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

2. Bagaimana cara menggunakan arahan yang berbeda, apa yang mereka lakukan masing-masing?

Arahan yang paling umum adalah:

  • default-src kebijakan default untuk memuat javascript, gambar, CSS, font, permintaan AJAX, dll
  • script-src mendefinisikan sumber yang valid untuk file javascript
  • style-src mendefinisikan sumber yang valid untuk file css
  • img-src mendefinisikan sumber yang valid untuk gambar
  • connect-srcmendefinisikan target yang valid untuk ke XMLHttpRequest (AJAX), WebSockets atau EventSource. Jika upaya koneksi dilakukan ke host yang tidak diizinkan di sini, browser akan meniru 400kesalahan

Ada yang lain, tetapi ini adalah yang paling mungkin Anda butuhkan.

3. Bagaimana cara menggunakan banyak arahan?

Anda mendefinisikan semua arahan Anda di dalam satu meta-tag dengan menghentikannya dengan tanda titik koma ( ;):

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

4. Bagaimana cara menangani port?

Semuanya kecuali port default harus diizinkan secara eksplisit dengan menambahkan nomor port atau tanda bintang setelah domain yang diizinkan:

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

Di atas akan menghasilkan:

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

Seperti yang saya sebutkan, Anda juga dapat menggunakan tanda bintang untuk secara eksplisit mengizinkan semua port:

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

5. Bagaimana menangani protokol yang berbeda?

Secara default, hanya protokol standar yang diizinkan. Misalnya untuk mengizinkan WebSockets, ws://Anda harus mengizinkannya secara eksplisit:

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

6. Bagaimana cara mengizinkan protokol file file://?

Jika Anda akan mencoba mendefinisikannya, maka tidak akan berfungsi. Sebagai gantinya, Anda akan mengizinkannya dengan filesystemparameter:

content="default-src filesystem"

7. Bagaimana cara menggunakan skrip inline dan definisi gaya?

Kecuali diizinkan secara eksplisit, Anda tidak dapat menggunakan definisi gaya inline, kode di dalam <script>tag atau di properti tag seperti onclick. Anda mengizinkannya seperti ini:

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

Anda juga harus secara eksplisit mengizinkan gambar yang disandikan sebaris, base64:

content="img-src data:"

8. Bagaimana cara mengizinkan eval()?

Saya yakin banyak orang akan mengatakan bahwa Anda tidak, karena 'eval is evil' dan kemungkinan besar penyebab akhir dunia yang akan datang. Orang-orang itu akan salah. Tentu, Anda pasti dapat membuat lubang besar ke keamanan situs Anda dengan eval, tetapi memiliki kasus penggunaan yang sangat valid. Anda hanya harus pandai menggunakannya. Anda mengizinkannya seperti ini:

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

9. Apa sebenarnya 'self'artinya?

Anda mungkin 'self'mengartikan localhost, filesystem lokal, atau apapun pada host yang sama. Itu tidak berarti semua itu. Ini berarti sumber yang memiliki skema (protokol) yang sama, host yang sama, dan port yang sama dengan file kebijakan konten didefinisikan. Melayani situs Anda melalui HTTP? Tidak ada https untuk Anda, kecuali Anda mendefinisikannya secara eksplisit.

Saya telah menggunakan 'self'sebagian besar contoh karena biasanya masuk akal untuk memasukkannya, tetapi itu tidak wajib. Biarkan saja jika Anda tidak membutuhkannya.

Tapi tunggu sebentar! Tidak bisakah saya hanya menggunakan content="default-src *"dan selesai dengan itu?

Tidak. Selain kerentanan keamanan yang jelas, ini juga tidak akan berfungsi seperti yang Anda harapkan. Meskipun beberapa dokumen mengklaim itu memungkinkan, itu tidak benar. Itu tidak memungkinkan inlining atau evals, jadi untuk benar-benar membuat situs Anda lebih rentan, Anda akan menggunakan ini:

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

... tapi saya percaya Anda tidak akan melakukannya.

Bacaan lebih lanjut:

http://content-security-policy.com

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

Schlaus
sumber
6
Pos yang bagus. Satu hal: tidak jelas apa yang terjadi ketika banyak arahan ditentukan; apakah pengaturan style-src pada contoh 3 lebih diutamakan daripada default-src? dll ...
track0
30
Jadi, untuk memungkinkan semuanya menjadi semua kontennyadefault-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
Penting untuk mengetahui bahwa content="default-src * 'unsafe-inline' 'unsafe-eval'"diperlukan untuk membuat beberapa aplikasi Angular bekerja.
flanger001
2
@Mahesh Itu "blog" penuh dengan posting yang disalin dari SO. Sepertinya tidak banyak pengguna SO yang akan menyalin konten dari blogger yang tidak dikenal - Saya tahu saya tidak.
Schlaus
2
Catatan singkat tentang connect-srcdan jalur: trailing slash adalah wajib jika Anda ingin memasukkan seluruh subpath. Misalnya: file http://foo.com/files/bar.txtakan diblokir jika sumbernya http://foo.com/files, tetapi disajikan ketika ituhttp://foo.com/files/
Griddo
15

APACHE2 MOD_HEADERS

Anda juga dapat mengaktifkan Apache2 mod_headers, di Fedora sudah diaktifkan secara default, jika Anda menggunakan Ubuntu / Debian, aktifkan seperti ini:

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

Di Ubuntu / Debian Anda dapat mengkonfigurasi header di file /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;"

Catatan: Ini adalah bagian bawah file, hanya 3 entri terakhir adalah pengaturan CSP.

Parameter pertama adalah arahan, yang ke-2 adalah sumber yang akan didaftar putih. Saya telah menambahkan Google analytics dan adserver, yang mungkin Anda miliki. Lebih lanjut saya menemukan bahwa jika Anda memiliki alias, mis., Www.example.com dan example.com dikonfigurasi dalam Apache2 Anda harus menambahkannya ke daftar putih juga.

Kode sebaris dianggap berbahaya, Anda harus menghindarinya. Salin semua javascripts dan css untuk memisahkan file dan menambahkannya ke daftar putih.

Saat Anda melakukannya, Anda bisa melihat pengaturan header lainnya dan menginstal mod_security

Bacaan lebih lanjut:

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

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

Erik Hendriks
sumber
2
Saya dapat menambahkan arahan yang sama ke file .htaccess saya, karena saya tidak memiliki kemampuan untuk mengedit konfigurasi Apache pada host bersama saya. Saya menemukan alat yang sangat baik untuk menyesuaikan pengaturan ini di report-uri.io/home/tools .
Michael McGinnis
Apakah ada cara untuk mengatasi ini dengan kucing jantan 7. Saya telah mencoba menambahkan filter dan tidak berhasil.
Elshan
0

Jangan lupa tentang font-src kerjanya sama seperti yang lain, tetapi jika Anda menggunakan font yang diambil dari asal lain - pastikan Anda menambahkannya ke meta tag

Mikhail Andrianov
sumber