The Content-Security-Policy
meta-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 content
properti, 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-src
mendefinisikan target yang valid untuk ke XMLHttpRequest (AJAX), WebSockets atau EventSource. Jika upaya koneksi dilakukan ke host yang tidak diizinkan di sini, browser akan meniru 400
kesalahan
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 filesystem
parameter:
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