29 Agustus 2020
Mencegah Eksekusi Kode Terinjeksi Menggunakan Content Security Policy

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.

Syntax

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]">

Directive

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

Nilai Directive

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

Contoh

Berikut ini beberapa contoh penggunaan directive CSP

Membatasi Penggunaan Kode Javascript

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

img001.png

img002.png

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

Penggunaan Dua atau Lebih Directive CSP

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 :

  1. Secara default, penggunaan konten apapun diperbolehkan hanya jika berasal dari sumber yang sama dengan halaman web
  2. Penggunaan kode javascript dan css diperbolehkan hanya jika berasal dari sumber yang sama atau berasal dari 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

img003.png

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