Apa Itu Content Security Policy (CSP)?


Content Security Policy (CSP) adalah lapisan keamanan tambahan pada aplikasi web yang berfungsi untuk mencegah berbagai serangan umum, seperti:

  • Cross-Site Scripting (XSS)
  • Data Injection Attack
  • Clickjacking
  • Loading resource berbahaya dari domain tidak terpercaya

CSP bekerja dengan cara mendefinisikan whitelist sumber resource apa saja yang boleh dijalankan oleh browser.

Ketika browser menemukan resource yang tidak sesuai aturan CSP, maka browser otomatis memblokirnya.

CSP diimplementasikan menggunakan HTTP Header yang memungkinkan server mendefinisikan aturan ketat terkait sumber konten yang diizinkan oleh browser.

Dengan CSP, developer dapat mengontrol:

  • Dari mana script boleh di-load
  • Apa saja jenis konten yang boleh dieksekusi
  • Domain mana yang diizinkan untuk komunikasi API
  • Domain mana yang boleh menggunakan iframe
  • Dan lainnya

Dengan kata lain, CSP mengurangi attack surface pada aplikasi modern.



Masalah Keamanan yang Diselesaikan CSP


CSP tidak hanya tentang XSS. CSP mengatasi berbagai ancaman, seperti:


1. XSS (Cross-Site Scripting)

Serangan XSS terjadi ketika penyerang menyuntikkan script jahat ke halaman web. CSP membatasi script apa yang boleh dijalankan.


2. Clickjacking

Penggunaan frame-ancestors mencegah situs lain meng-embed halaman Anda.


3. Injection Attack

CSP membatasi API endpoint sehingga request ke domain ilegal dapat diblokir.


4. Data Exfiltration

Dengan memblokir koneksi ke domain asing, pencurian data bisa dicegah.


5. Supply Chain Attacks

Serangan melalui third-party script (misalnya script CDN yang di-hijack).




Bagaimana CSP Bekerja


Browser memvalidasi setiap resource di halaman—script, image, CSS, iframe, request API—berdasarkan rule CSP yang dikirim server melalui header:

Content-Security-Policy: <directive> <value>;

Jika resource tidak sesuai aturan, browser akan:

  1. Memblokir resource
  2. Melaporkan pelanggaran (jika report-to atau report-uri diaktifkan)


Direktif CSP yang Paling Penting & Fungsinya



default-src

Menjadi default untuk semua direktif lain.

default-src 'self';

Jika script-src, style-src, dll tidak didefinisikan — maka akan mengikuti aturan default-src.

Contoh kasus:

Jika Anda lupa mendefinisikan img-src, dan default-src 'none', maka semua gambar diblokir.


script-src — Direktif Terpenting

Mengatur sumber JavaScript.

Opsi umum:

  • 'self' — hanya domain sendiri
  • 'nonce-randomvalue'— inline script aman
  • 'sha256-...' — fingerprint script tertentu
  • 'unsafe-inline' — tidak disarankan
  • 'strict-dynamic' — cocok untuk SPA modern
  • 'unsafe-eval' — harus dihindari
Contoh dengan nonce
script-src 'self' 'nonce-8439rjfsdf8932r';
Kasus penggunaan nyata:
  • React SSR sering memerlukan nonce untuk hydration.
  • Angular dapat memanfaatkan strict-dynamic.

style-src

Mengatur sumber CSS.

SPA sering butuh inline CSS, tapi tetap bisa dikontrol.

style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;

img-src

Resource gambar.

img-src 'self' data: blob: https:;
Catatan:
  • data: digunakan untuk base64 image
  • blob: digunakan oleh canvas atau WebRTC capture

font-src

Font dari CDN atau self-host.

font-src 'self' https://fonts.gstatic.com;

connect-src

Untuk:

Kasus AWS:
connect-src 'self' https://cognito-idp.ap-southeast-1.amazonaws.com;

frame-src

Untuk iframe embed.

frame-src https://www.youtube.com/ https://maps.google.com/;

frame-ancestors (Pengganti X-Frame-Options)

Melindungi dari clickjacking.

frame-ancestors 'none';

object-src

Untuk plugin lama. Selalu set ‘none’.

object-src 'none';

manifest-src

Untuk PWA.

manifest-src 'self';

form-action

Mencegah form submit ke domain berbahaya.

form-action 'self' https://secure.payment.com;

media-src

Untuk video/audio.


report-uri & report-to

Untuk menerima laporan pelanggaran CSP.

report-to csp-endpoint;


CSP Level 3 — Fitur Modern


CSP Level 3 memperkenalkan:

1. strict-dynamic

Membuat script baru yang dimuat oleh script valid ikut dianggap valid.

2. Nonce-Based CSP

Semakin direkomendasikan oleh browser modern.

3. Modernized Reporting

Menggunakan report-to dibanding report-uri.



Contoh CSP Ideal untuk Berbagai Jenis Aplikasi


CSP untuk Aplikasi Enterprise Standard
Content-Security-Policy:
  default-src 'self';
  script-src 'self';
  img-src 'self';
  style-src 'self';
  object-src 'none';

CSP untuk SPA Modern (Angular / React / Vue)
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{{NONCE}}' 'strict-dynamic';
  style-src 'self' 'unsafe-inline';
  img-src 'self' blob: data:;
  connect-src 'self' https://api.example.com;
  font-src 'self' https://fonts.gstatic.com;
  base-uri 'self';
  frame-ancestors 'none';
  object-src 'none';

CSP untuk Aplikasi AWS (Cognito, Amplify, API Gateway)
Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-{{NONCE}}';
  connect-src 'self'
    https://cognito-idp.ap-southeast-1.amazonaws.com
    https://api.example.com
    https://*.amazonaws.com;
  img-src 'self' data: blob:;
  style-src 'self' 'unsafe-inline';
  frame-ancestors 'none';
  object-src 'none';


Debugging CSP


Gunakan Mode Report-Only

Untuk testing di production tanpa memblok resource.

Content-Security-Policy-Report-Only: ...
6.2. Browser Tools
  • Chrome → DevTools → Security → CSP Violations
  • Firefox → Console → CSP Warning
6.3. Common Errors
  1. Inline scripts diblok
  2. CDN tidak di-whitelist
  3. WebSocket diblok
  4. Iframe dari 3rd party gagal tampil


Checklist Best Practice CSP


Do
  • Gunakan 'nonce' atau 'sha256'
  • Set object-src 'none'
  • Gunakan frame-ancestors
  • Tes dulu dengan report-only
  • Gunakan 'strict-dynamic' di modern framework
Don’t
  • Jangan pakai 'unsafe-inline' pada script
  • Jangan pakai wildcard *
  • Jangan izinkan third-party tanpa trust yang kuat
  • Jangan biarkan default-src terlalu longgar

Kesimpulan

Content Security Policy merupakan komponen keamanan fundamental untuk aplikasi web modern. Dengan implementasi yang benar, CSP mampu mengurangi risiko dari XSS, clickjacking, supply chain attack, hingga data exfiltration.

Developer dan arsitek harus memahami direktif seperti script-src, default-src, connect-src, serta penggunaan nonce/hash agar aplikasi tetap aman dan tetap kompatibel dengan framework modern.