Third-Party Script Risks — Security

Risiko Third-Party Scripts Hampir semua website modern memuat script dari pihak ketiga: analytics, ads, chat widgets, social media embeds. Setiap script…

Script pihak ketiga adalah JavaScript yang kamu muat dari server orang lain: analytics, widget live chat, iklan, atau library dari CDN. Satu baris <script src> memberi kode itu akses yang sama persis dengan kodemu sendiri. Bayangin kamu menitipkan kunci rumah ke jasa bersih-bersih. Kuncinya membuka semua kamar, bukan cuma dapur. Dan kalau kantor jasa itu kebobolan, pencurinya ikut pegang kunci rumahmu.

🧪 Tebakan cepat: halaman checkout-mu memuat <script src="https://widget.example.net/chat.js">. Bisa gak script itu membaca nomor kartu yang diketik di form checkout-mu? Tebak dulu, jawabannya ada di bagian "Script pihak ketiga jalan dengan hak penuh".

Script pihak ketiga jalan dengan hak penuh

Browser gak membedakan script milikmu dan script dari domain lain. Begitu dimuat lewat <script src>, script itu jalan di dalam halamanmu, dengan origin halamanmu. Same-origin policy (aturan browser yang memisahkan satu origin dari origin lain) gak menolong di sini, karena bagi browser script itu bagian dari halamanmu. Jadi script chat tadi bisa:

Itu jawaban tebakannya: bisa. Selama dia jalan di halamanmu, nomor kartu di form ikut terbaca.

Ini bukan berarti vendor-nya jahat. Risikonya ada di rantai pasokan: kalau server, CDN, atau akun vendor itu dibobol, kode penyerang ikut jalan di semua situs yang memuatnya. Serangan lewat pemasok seperti ini disebut supply chain attack. Contoh nyata: tahun 2024 domain polyfill.io pindah tangan, lalu script-nya mulai menyisipkan kode jahat ke lebih dari 100.000 situs yang memuatnya.

Inventaris: catat dan nilai setiap tag

Langkah pertama defender: daftar semua tag pihak ketiga di halaman, lalu nilai satu per satu. Ini inventaris halaman https://tokokopi.example.com/checkout, sama dengan yang ada di Lab:

Tag Lewat HTTPS? Isinya dikunci? Perlu menyentuh halaman?
/js/app.js ya, origin sendiri gak perlu, file sendiri ya, ini kode toko
dayjs.min.js dari cdn.jsdelivr.net ya belum ya, dipanggil kode toko
analytics.js dari cdn.example.com tidak, masih http:// gak bisa, vendor mengubahnya ya, tugasnya mengukur halaman
chat.js dari widget.example.net ya gak bisa, vendor mengubahnya tidak, cuma butuh kotaknya sendiri

Dari tabel itu keluar tiga perbaikan:

  1. http:// jadi https://. Script lewat http:// bisa diubah siapa pun di jaringan yang sama (Wi-Fi publik, router), ini disebut serangan man-in-the-middle. Di halaman HTTPS, browser modern malah langsung memblokirnya sebagai mixed content, jadi fiturnya juga mati.
  2. File berversi dikunci dengan SRI. [email protected] gak akan berubah, jadi isinya bisa dikunci.
  3. Yang gak perlu menyentuh halaman dipindah ke iframe. Widget chat cukup jalan di kotaknya sendiri.

SRI: kunci isi file dengan hash

SRI (Subresource Integrity) adalah atribut integrity berisi hash dari isi file. Browser menghitung hash file yang datang dan menolak menjalankannya kalau beda satu byte pun. Hash-nya dibuat sekali dari file aslinya:

$ curl -s https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js | openssl dgst -sha384 -binary | openssl base64 -A
DpVxUeeBWjUvUV1czyIHJAjh+jYUZFu2lLakbdua5vbwOrBGi1UgaKCHjTC+x3Ky
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js"
        integrity="sha384-DpVxUeeBWjUvUV1czyIHJAjh+jYUZFu2lLakbdua5vbwOrBGi1UgaKCHjTC+x3Ky"
        crossorigin="anonymous" defer></script>

SRI cuma cocok untuk file yang isinya tetap. analytics.js dan chat.js diubah vendornya kapan saja, jadi hash-nya bakal basi.

CSP: daftar host yang boleh

CSP (Content Security Policy) adalah aturan dari halaman ke browser: script dan iframe boleh datang dari mana saja. Isinya diambil dari inventaris tadi:

<meta http-equiv="Content-Security-Policy"
      content="script-src 'self' https://cdn.jsdelivr.net https://cdn.example.com; frame-src https://widget.example.net">

Widget di iframe sandbox

Widget chat gak perlu membaca form checkout-mu. Muat dia sebagai halaman terpisah:

<iframe src="https://widget.example.net/embed"
        sandbox="allow-scripts allow-forms allow-popups"
        title="Chat"></iframe>

⚠️ Jebakan yang sering ketemu

TL;DR: Script pihak ketiga jalan dengan hak yang sama dengan kodemu, jadi kalau pemasoknya dibobol (supply chain attack), kode penyerang jalan di halamanmu. Catat setiap tag di inventaris dan nilai: wajib https:// (http:// bisa diubah di jalan dan diblokir di halaman HTTPS), file berversi dikunci dengan integrity plus crossorigin="anonymous", CSP script-src cuma berisi host dari inventaris, dan widget yang gak perlu menyentuh halamanmu dipindah ke iframe dengan atribut sandbox.

Yang akan kamu pelajari