Episode ini membahas keamanan saat mengambil data: konsumsi API yang aman dan penanganan token, perlindungan dari CSRF dan XSS serta secure rendering, sanitasi input dan safe string handling, serta praktik terbaik untuk data sensitif.

Fetching data hanyalah setengah pekerjaan; setengahnya lagi adalah memastikan data yang masuk dan keluar tidak membuka celah keamanan. Token yang bocor, input yang tidak divalidasi, atau HTML yang dirender tanpa sanitasi adalah jalan masuk favorit penyerang.
Episode ini membahas konsumsi API yang aman dan penanganan token, perlindungan dari CSRF dan XSS, sanitasi input dan safe string handling, serta praktik terbaik untuk data sensitif.
Setelah selesai, kalian bisa mengambil data dari layanan eksternal tanpa khawatir secret bocor dan tanpa membuka pintu bagi injeksi. Pola yang dipelajari di sini menjadi fondasi kebijakan keamanan yang dibahas lebih luas di episode 14.
Token di query string bocor lewat log server, history browser, dan header referer. Kirim token lewat header Authorization, dan lakukan fetching di server bila memungkinkan:
import { API_TOKEN } from "$env/static/private"
export async function load({ fetch }) {
const res = await fetch("https://api.example.com/v1/users", {
headers: {
Authorization: `Bearer ${API_TOKEN}`,
},
})
if (!res.ok) {
throw new Error("Gagal mengambil data dari API")
}
return { users: await res.json() }
}API_TOKEN diimpor dari $env/static/private, sehingga hanya ada di server dan tidak pernah masuk ke bundle klien. Template literal `Bearer ${API_TOKEN}` menyisipkan token tanpa menyentuh query string.
Simpan token sesingkat mungkin. Token dengan umur panjang yang bocor adalah bencana. Pola umum: access token pendek untuk tiap request dan refresh token berumur lebih lama yang hanya dipertukarkan di server. Jika mencurigai kebocoran, cabut token sesegera mungkin.
CSRF membuat browser pengguna yang sedang login menjalankan aksi atas nama mereka tanpa sepengetahuan pemiliknya. SvelteKit menawarkan perlindungan bawaan: form actions memvalidasi sumber request, dan cookie dengan sameSite: "lax" mencegah kebanyakan serangan lintas situs.
Svelte melakukan escaping pada semua interpolasi seperti {nama} secara default. Risiko muncul saat kalian memaksa Svelte merender HTML mentah dengan {@html}. Setiap konten yang tidak sepenuhnya dipercaya harus disanitasi dulu:
<script>
import DOMPurify from "dompurify"
let { konten } = $props()
const bersih = DOMPurify.sanitize(konten)
</script>
<div>{@html bersih}</div>DOMPurify.sanitize(konten) menghapus skrip dan atribut berbahaya dari HTML sebelum dirender. Ingat aturan emasnya: sanitasi dilakukan di server, bukan di browser, karena klien bisa dimanipulasi.
Validasi hanya di client tidak cukup — siapa pun bisa membuka DevTools dan menghapus aturan tersebut. Validasi ulang semua input di server sebelum digunakan:
import { z } from "zod"
import { fail } from "@sveltejs/kit"
const skemaForm = z.object({
nama: z.string().trim().min(3).max(80),
email: z.string().trim().email(),
umur: z.coerce.number().int().min(18),
})
export const actions = {
async daftar({ request }) {
const data = Object.fromEntries(await request.formData())
const hasil = skemaForm.safeParse(data)
if (!hasil.success) {
return fail(400, { pesan: "Data tidak valid" })
}
return { sukses: true, nama: hasil.data.nama }
},
}z.string().email() memastikan format email benar dan z.coerce.number() mengubah string dari form menjadi angka. safeParse mengembalikan hasil yang bisa dicek tanpa melempar error.
Aturan kedua setelah validasi adalah escaping. Jangan pernah menggabungkan input user langsung ke SQL, HTML, atau URL. Gunakan parameterized queries untuk database dan biarkan Svelte menangani escaping markup. Prinsip yang sama berlaku untuk JSON yang dikirim ke endpoint lain.
Kurangi data sensitif yang dipindahkan. Kirim hanya kolom yang dibutuhkan UI, jangan pernah mengirim hash password atau token dari server ke klien. Bentuk objek user yang aman di server sebelum sampai ke load function.
$env/static/private atau secret manager.Authorization, bukan query string.sameSite dan httpOnly pada semua cookie session.Inti yang harus dibawa pulang:
sameSite.{@html} sebelum dirender.Di episode 14 selanjutnya kita akan membahas content security & performance — Content Security Policy dan secure headers, strategi caching dan optimasi resource, optimasi gambar dengan lazy loading, serta monitoring performa jaringan. Pola sanitasi dari episode ini akan menjadi dasar kebijakan keamanan yang lebih luas.