Content Security Policy (CSP) merupakan standar keamanan yang diperkenalkan oleh W3C dengan tujuan untuk mencegah eksekusi kode terinjeksi dalam halaman web. CSP memungkinkan web developer untuk mengendalikan konten apa saja yang bisa di-load atau dieksekusi berdasarkan sumber (origin) dari konten tersebut. Konten yang dimaksud meliputi kode javascript, CSS, gambar, iframe dan lain sebagainya.
Dalam website W3C, CSP didefinisikan sebagai :
Alat yang bisa digunakan oleh developer untuk mengunci aplikasi mereka dengan beragam cara, (dengan tujuan) mengurangi resiko dari kelemahan injeksi konten seperti cross-site scripting, dan menurunkan hak istimewa yang digunakan dalam eksekusi aplikasi
CSP diaktifkan dari sisi web server dengan menambahkan Content-Security-Policy
dalam header dari response HTTP. Jika ini tidak dimungkinkan, cara lain adalah dengan menambahkan elemen <meta http-equiv="Content-Security-Policy">
dalam dokumen HTML.
Kebijakan (policy) dalam CSP terdiri atas sejumlah directive yang dipisahkan dengan simbol titik koma. Tiap directive terdiri atas kombinasi nama dan nilai yang dipisahkan dengan spasi.
Dalam header HTTP, CSP ditulis menggunakan syntax berikut :
Content-Security-Policy: [directive-name] [directive-value]; [directive-name] [directive-value]
Sedangkan dalam elemen <meta>
, CSP ditulis dengan syntax berikut :
<meta http-equiv="Content-Security-Policy" content="[directive-name] [directive-value]; [directive-name] [directive-value]">
Berikut beberapa directive dasar dalam CSP
script-src
: Digunakan untuk menentukan sumber valid untuk kode javascript
style-src
: Digunakan untuk menentukan sumber valid untuk kode CSS.
img-src
: Digunakan untuk menentukan sumber valid untuk gambar (image).
font-src
: Digunakan untuk menentukan sumber valid untuk font
default-src
: Mewakili directive lain dalam CSP, digunakan untuk menentukan nilai default yang akan dijadikan rujukan jika directive tertentu tidak ditemukan
Berikut ini adalah beberapa nilai yang bisa digunakan dalam directive CSP
self
dan none
: self
mengizinkan pengambilan resource dari sumber yang sama dengan halaman yang diakses, sedangkan none
tidak mengizinkan pengambilan resource dari sumber manapun
Domain dan Subdomain
: Mengizinkan pengambilan resource yang bersumber dari domain/subdomain yang ditentukan. Penulisan yang bisa digunakan dalam directive CSP antara lain : example.com
, http://example.com
, subdomain.example.com
, *.example.com
, dan http://subdomain.example.com
data:
: Mengizinkan penggunaan resource melalui skema data:
unsafe-inline
: Mengizinkan penggunaan kode internal atau inline.
Dalam draft CSP disebutkan, penggunaan skema data:
dan unsafe-inline
harus dihindari karena membuka peluang untuk eksekusi kode yang terinjeksi kedalam halaman web
Berikut ini beberapa contoh penggunaan directive
CSP
Kebijakan CSP berikut ini membatasi penggunaan kode javascript hanya yang berasal dari sumber yang sama atau yang berasal dari http://cdnjs.cloudflare.com
.
Content-Security-Policy: script-src 'self' cdnjs.cloudflare.com
Kebijakan CSP tersebut akan mempengaruhi penggunaan kode javascript dalam halaman web, perhatikan contoh berikut :
<script type="text/javascript" src="/js/script.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
Elemen <script>
yang pertama dan kedua akan dieksekusi seperti biasa, sementara elemen yang ketiga akan diblokir oleh web browser karena domain sumber (ajax.googleapis.com
) tidak terdaftar dalam directive CSP.
Selain membatasi pengambilan dan eksekusi kode eksternal, kebijakan CSP tersebut juga akan mencekal eksekusi kode internal, seperti kode yang ditulis dalam elemen <script>
atau kode yang dimasukkan dalam atribut event seperti onClick
atau onLoad
.
Sebagai contoh :
<button type="button" name="button" onclick="myOtherFunc()">Test</button>
<script type="text/javascript">
function myOtherFunc() {
console.log('this doesn\'t work');
}
console.log('test!');
</script>
Pengaruh dari kebijakan CSP diatas dapat dilihat langsung dalam web browser
Pada kutipan layar diatas terlihat bahwa browser mencekal request ke ajax.googleapis.com
dan penggunaan kode yang ditulis secara inline.
Untuk mengizinkan penggunaan kode javascript internal atau inline dalam halaman web, yang perlu dilakukan adalah dengan menambahkan unsafe-inline
kedalam directive script-src
Content-Security-Policy: script-src 'self' 'unsafe-inline' cdnjs.cloudflare.com
Pada contoh berikut, kebijakan CSP akan menggunakan beberapa directive sekaligus. Contoh ini akan menggunakan library Semantic UI yang diakses melalui cdnjs.
Berikut ini adalah kode javascript/css yang digunakan dalam semantic-ui disertai tambahan kode khusus yang akan digunakan dalam halaman web
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
<link rel="stylesheet" type="text/css" href="/css/style.css"> <!-- same origin -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
<script type="text/javascript" src="/js/script.js"></script> <!-- same origin -->
Berdasarkan kode HTML tersebut, Didefinisikan kebijakan CSP awal sebagai berikut :
cdnjs.cloudflare.com
Content-Security-Policy: default-src 'self'; script-src 'self' cdnjs.cloudflare.com; style-src 'self' cdnjs.cloudflare.com
Penerapan kebijakan CSP diatas akan menghasilkan pesan error yang bisa dilihat pada console browser
Hal ini disebabkan karena file semantic.min.css
mencoba mengirim request ke beberapa sumber eksternal. Jika diperhatikan, file semantic.min.css
menggunakan rule seperti @import
dan @font-face
yang memicu pengiriman request tersebut. Agar library ini bisa berfungsi dengan baik, penggunaan resource eksternal harus diizinkan
Yang perlu dikerjakan selanjutnya adalah menambahkan sumber-sumber eksternal tersebut kedalam directive CSP. Sumber yang perlu ditambahkan antara lain : fonts.googleapis.com
kedalam directive style-src
, Skema data:
, fonts.gstatic.com
, dan cdnjs.cloudflare.com
kedalam directive baru font-src
.
Content-Security-Policy: default-src 'self'; script-src 'self' cdnjs.cloudflare.com; style-src 'self' cdnjs.cloudflare.com fonts.googleapis.com; font-src data: fonts.gstatic.com cdnjs.cloudflare.com