Belajar SvelteKit - Secure Data Fetching
Episode 13 of 24

Belajar SvelteKit - Secure Data Fetching

Episode ini membahas keamanan pada pengambilan data: request API yang aman dengan auth headers, handling secrets dan server-only config, perlindungan CSRF dan XSS, input sanitization, serta konfigurasi deployment yang aman.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Setelah mempelajari authentication di episode 12, episode 13 berfokus pada keamanan pengambilan dan pengiriman data. Ini adalah lapisan pertahanan yang paling sering diabaikan: request API yang bocor token, secret yang tertanam di bundle client, hingga input yang tidak dibersihkan.

SvelteKit memberikan batas yang jelas antara server dan client, tetapi batas itu hanya berguna jika dimanfaatkan dengan benar. Semua data sensitif harus tetap berada di sisi server, dan setiap jalur masuk data dari pengguna harus diverifikasi.

Setelah episode ini, kalian bisa menulis aplikasi yang memegang secret dengan benar, menolak request yang mencurigakan, dan membersihkan input sebelum disimpan atau dirender.

Secure API Requests dan Auth Headers

Fetch dengan Auth Header di Server

Panggilan API eksternal yang butuh token dilakukan dari load function server, bukan dari browser. Token dibaca dari environment variable dan disisipkan lewat header Authorization, tanpa pernah terlihat oleh JavaScript di client.

JSFetch API dengan auth header
export const load = async ({ fetch }) => {
    const res = await fetch("https://api.example.com/me", {
        headers: {
            Authorization: `Bearer ${process.env.API_TOKEN}`
        }
    });
 
    if (!res.ok) {
        throw error(502, "Gagal mengambil data dari layanan eksternal");
    }
 
    return { data: await res.json() };
};

Load function server tidak pernah dikirim ke browser; hanya nilai yang dikembalikan yang di-serialisasi. Karena itu token aman selama kalian tidak menyimpan secret di dalam nilai yang dikembalikan.

Mencegah Kebocoran Token ke Client

Periksa setiap nilai yang dikembalikan load function. Jangan mengembalikan objek user yang berisi passwordHash, apiKey, atau token mentah. Pilih hanya field yang dibutuhkan UI, atau bangun objek baru secara eksplisit agar struktur yang dipakai UI tidak menyeret data internal.

JSMemilih field yang aman untuk client
export const load = async ({ locals }) => {
    const user = locals.user;
 
    return {
        profil: {
            id: user.id,
            nama: user.nama,
            avatar: user.avatar
        }
    };
};

Handling Secrets dan Server-Only Config

Environment Variable dengan Prefix

Di SvelteKit, variabel yang diawali PUBLIC_ bisa diakses dari client lewat import.meta.env.PUBLIC_NAMA. Semua secret harus disimpan di environment variable tanpa prefix dan hanya dibaca di server, misalnya melalui modul di src/lib/server.

JSConfig server-only
const env = import.meta.env;
 
export const config = {
    databaseUrl: env.DATABASE_URL,
    apiToken: env.API_TOKEN
};
 
if (!config.databaseUrl || !config.apiToken) {
    throw new Error("Environment variable tidak lengkap");
}

File di src/lib/server hanya bisa diimpor dari kode server. Impor dari komponen client akan gagal di build, sehingga secret yang bersembunyi di sana tidak bisa bocor tanpa sengaja.

Validasi Environment Saat Start

Validasi environment di awal startup mencegah aplikasi berjalan dengan konfigurasi yang salah. Skema validasi bisa ditulis manual atau memakai pustaka seperti Zod. Dengan npm install zod, kalian bisa memeriksa kehadiran dan format tiap variabel sekali, lalu memakai hasilnya di seluruh server.

Perlindungan CSRF dan XSS

CSRF dengan sameSite dan Origin Check

Cookie sameSite mencegah sebagian besar serangan CSRF, tetapi untuk request yang dikirim lintas origin, verifikasi header Origin menambah lapisan pertahanan. Server action yang sensitif sebaiknya memastikan origin request cocok dengan origin aplikasi.

JSVerifikasi origin di server action
import { error } from "@sveltejs/kit";
 
export const actions = {
    ubahEmail: async ({ request }) => {
        const origin = request.headers.get("origin");
        const izinkan = process.env.ALLOWED_ORIGINS.split(",");
 
        if (!origin || !izinkan.includes(origin)) {
            throw error(403, "Origin tidak diizinkan");
        }
 
        const form = await request.formData();
        const email = String(form.get("email") ?? "");
 
        return { sukses: true };
    }
};

XSS dan Escaping Otomatis

Svelte men-escape semua nilai yang dirender lewat kurung kurawal, sehingga XSS lewat ekspresi umum bisa dicegah. Bahayanya muncul ketika kalian memakai {@html} untuk merender HTML mentah — nilai itu harus disanitasi dulu dengan pustaka seperti sanitize-html atau DOMPurify sebelum dirender.

Merender HTML yang sudah dibersihkan
<script>
    import DOMPurify from "dompurify";
    import { browser } from "$app/environment";
 
    let { konten } = $props();
    let htmlAman = browser ? DOMPurify.sanitize(konten) : konten;
</script>
 
{@html htmlAman}

Input Sanitization dan Deployment Aman

Query Parameterized

Input dari user yang masuk ke SQL harus melewati parameterized query, bukan digabungkan langsung ke string. Dengan cara ini, isi input diperlakukan sebagai data, bukan bagian dari perintah, sehingga injeksi SQL kehilangan medianya.

JSQuery aman dengan parameter
import db from "$lib/server/db";
 
export const load = async ({ url }) => {
    const nama = url.searchParams.get("nama") ?? "";
 
    const hasil = await db.query(
        "SELECT * FROM pengguna WHERE nama ILIKE $1",
        [`%${nama}%`]
    );
 
    return { hasil };
};

Prinsip yang sama berlaku untuk library lain: selalu pakai mekanisme parameter bawaan ORM atau driver database, dan hindari membangun query dari string yang bisa mengandung input pengguna.

Security Headers di Produksi

Lengkapi deployment dengan security headers: Content-Security-Policy untuk membatasi sumber skrip, Strict-Transport-Security untuk memaksa HTTPS, serta X-Content-Type-Options: nosniff. SvelteKit tidak menambahkan header ini secara otomatis, jadi pasang di platform hosting atau middleware platform kalian.

Penutup

Inti yang harus dibawa pulang:

  • Token API disisipkan di header Authorization dari server, bukan dari client.
  • Jangan pernah mengembalikan secret di nilai yang dikembalikan load function.
  • Secret hanya dibaca di src/lib/server dan divalidasi saat aplikasi start.
  • Cookie sameSite plus verifikasi origin melawan CSRF.
  • Svelte men-escape output; sanitasi dulu sebelum memakai {@html}.
  • Gunakan parameterized query dan pasang security headers di produksi.

Di episode 14 selanjutnya kita membahas caching & performance: caching headers dan revalidation, static generation, prerendering, streaming, edge caching dan integrasi CDN, serta performance budgets dan monitoring.

Belajar SvelteKit - Secure Data Fetching | Belajar SvelteKit