Belajar Next.js - API Security & Data Protection
Episode 13 of 24

Belajar Next.js - API Security & Data Protection

Episode ini membahas pengamanan route handler dan validasi request dengan Zod, CORS dan CSRF dengan secure headers, penanganan data sensitif dan secrets, serta rate limiting dan pencegahan penyalahgunaan API.

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

Pendahuluan

API adalah permukaan serangan utama sebuah aplikasi. Endpoint yang menerima input dari publik — tanpa validasi, tanpa batasan, tanpa keamanan header — adalah undangan terbuka bagi penyalahgunaan.

Episode 13 membahas pengamanan route handler dan validasi request dengan Zod, konfigurasi CORS dan proteksi CSRF dengan secure headers, penanganan data sensitif dan secrets, serta rate limiting dan pencegahan penyalahgunaan.

Secure API Routes dan Request Validation

Validasi Input di Setiap Endpoint

Aturan nomor satu: jangan pernah mempercayai input. Setiap body, query, dan header dari request harus divalidasi sebelum dipakai. Kombinasikan Zod dengan route handler:

Route handler dengan validasi Zod
import { NextResponse } from "next/server"
import { z } from "zod"
 
const schema = z.object({
  email: z.string().email(),
  nama: z.string().min(3).max(100),
})
 
export async function POST(request) {
  const body = await request.json()
  const parsed = schema.safeParse(body)
 
  if (!parsed.success) {
    return NextResponse.json(
      { error: "Data tidak valid" },
      { status: 400 }
    )
  }
 
  const data = parsed.data
  return NextResponse.json({ ok: true, data }, { status: 201 })
}

schema.safeParse(body) memvalidasi seluruh body. Mengembalikan status 400 saat validasi gagal mencegah data kotor masuk ke logika aplikasi.

Batasi Ukuran dan Tipe Data

Terapkan batas pada input: panjang string, jumlah item dalam array, dan nilai maksimum untuk angka. Validasi server juga harus menyaring input berbahaya seperti SQL injection — selalu gunakan prepared statement atau ORM saat berinteraksi dengan database, jangan menyusun query dari string langsung.

CORS, CSRF, dan Secure Headers

Konfigurasi CORS

CORS (Cross-Origin Resource Sharing) menentukan domain mana yang boleh memanggil API kalian. Di route handler, atur header secara eksplisit:

Mengatur header CORS
export async function GET() {
  const headers = new Headers()
  headers.set("Access-Control-Allow-Origin", "https://app.example.com")
  headers.set("Access-Control-Allow-Methods", "GET, POST")
 
  return NextResponse.json({ data: [] }, { headers })
}

Header Access-Control-Allow-Origin di atas membatasi pemanggilan ke domain app.example.com. Jangan memakai wildcard untuk API yang membawa data pengguna.

Proteksi CSRF dan Secure Headers

CSRF menyerang aplikasi yang mempercayai cookie secara implisit. Server Actions Next.js dilindungi bawaan, tapi untuk route handler yang memakai cookie sesi, pastikan ada token CSRF. Lengkapi juga dengan secure headers:

  • X-Frame-Options: DENY mencegah clickjacking.
  • X-Content-Type-Options: nosniff mencegah sniffing tipe konten.
  • Strict-Transport-Security memaksa koneksi HTTPS.
  • Content-Security-Policy membatasi sumber script dan style.

Header di atas bisa ditetapkan otomatis lewat opsi headers di next.config.mjs, sehingga berlaku untuk seluruh response.

Handling Sensitive Data dan Secrets

Memisahkan Secret dari Kode

Secrets seperti kunci API, token database, dan kunci signing hanya boleh eksis di environment server. Jangan pernah: menaruhnya di kode, menaruhnya di variabel NEXT_PUBLIC_, atau menaruhnya di riwayat Git. Gunakan file .env.local (yang masuk .gitignore) dan inject nilai asli dari platform deployment di production.

Enkripsi dan Hapus Data yang Tidak Perlu

Data sensitif seperti password wajib di-hash — jangan pernah menyimpan password plaintext. Gunakan library seperti bcrypt dengan salt. Prinsip data minimization: simpan hanya data yang benar-benar dibutuhkan, dan hapus atau anonimkan data lama. Semakin sedikit data sensitif yang tersimpan, semakin kecil dampaknya saat terjadi kebocoran.

Rate Limiting dan Abuse Prevention

Membatasi Frekuensi Request

API publik wajib dibatasi frekuensinya untuk mencegah brute force dan spam. Di edge, gunakan penyimpanan terdistribusi seperti Upstash Redis:

Rate limiting dengan Upstash
import { Ratelimit } from "@upstash/ratelimit"
import { Redis } from "@upstash/redis"
 
const ratelimit = new Ratelimit({
  redis: Redis.fromEnv(),
  limiter: Ratelimit.slidingWindow(10, "1 m"),
})
 
export async function POST(request) {
  const ip = request.headers.get("x-forwarded-for")
  const result = await ratelimit.limit(`api-${ip}`)
 
  if (!result.success) {
    return new Response("Terlalu banyak permintaan", { status: 429 })
  }
 
  return new Response("OK")
}

ratelimit.limit("api-" + ip) mengembalikan success yang menandakan apakah request melebihi kuota 10 request per menit. Status 429 menandakan Too Many Requests.

Penutup

Inti yang harus dibawa pulang:

  • Validasi semua input dengan skema seperti Zod di setiap endpoint.
  • CORS dibatasi ke domain yang diizinkan, bukan wildcard.
  • Secure headers melindungi dari clickjacking dan sniffing.
  • Secrets hanya di environment server, tidak pernah di kode.
  • Password wajib di-hash dan data sensitif diminimalkan.
  • Rate limiting mencegah brute force dan penyalahgunaan API.

Di episode 14 selanjutnya kita akan membahas networking performance dan caching — strategi caching dengan Cache-Control dan ISR, edge caching dan integrasi CDN, optimasi pengambilan data untuk mengurangi latensi API, serta prefetching dan resource scheduling. Aplikasi kalian akan terasa jauh lebih cepat.

Belajar Next.js - API Security & Data Protection | Belajar Next.js