Kembali ke Blog
Tutorial#keamanan web#security#owasp#xss#sql injection#2026

Keamanan Web untuk Developer: OWASP Top 10 dan Cara Mencegahnya di 2026

Setiap developer bertanggung jawab atas keamanan kode yang mereka tulis. Kenali 10 celah keamanan web paling berbahaya versi OWASP dan cara konkret mencegahnya di aplikasi Anda.

Muhamad Putra Aulia Hidayat

Muhamad Putra Aulia Hidayat

8 Maret 20263 menit baca

Keamanan Web: Tanggung Jawab Setiap Developer

Breach data bukan hanya masalah perusahaan besar. UMKM dan startup juga sering jadi target karena keamanannya lemah. Ini panduan praktis berdasarkan OWASP Top 10.

1. Broken Access Control

Penyebab terbesar data breach. User bisa akses data yang bukan miliknya.

// BURUK - tidak ada cek kepemilikan
export async function GET(req: Request, { params }: { params: { id: string } }) {
  const { id } = await params
  const order = await db.query("SELECT * FROM orders WHERE id = $1", [id])
  return Response.json(order) // Siapa saja bisa akses order orang lain!
}

// BENAR - verifikasi kepemilikan
export async function GET(req: Request, { params }: { params: { id: string } }) {
  const { id } = await params
  const user = await getAuthUser(req)

  if (!user) return Response.json({ error: "Unauthorized" }, { status: 401 })

  const order = await db.query(
    "SELECT * FROM orders WHERE id = $1 AND user_id = $2",
    [id, user.id] // Paksa filter berdasarkan user
  )

  if (!order) return Response.json({ error: "Not found" }, { status: 404 })
  return Response.json(order)
}

Di Supabase, pakai Row Level Security:

CREATE POLICY "Users see own orders"
  ON orders FOR SELECT
  USING (user_id = auth.uid());

2. SQL Injection

// BURUK
const query = `SELECT * FROM users WHERE email = '${email}'`

// BENAR
const user = await db.query("SELECT * FROM users WHERE email = $1", [email])

3. Cross-Site Scripting (XSS)

// BURUK
function Comment({ content }: { content: string }) {
  return <div dangerouslySetInnerHTML={{ __html: content }} />
}

// BENAR
import DOMPurify from "dompurify"

function Comment({ content }: { content: string }) {
  const clean = DOMPurify.sanitize(content)
  return <div dangerouslySetInnerHTML={{ __html: clean }} />
}

4. Security Headers

// next.config.js
const securityHeaders = [
  { key: "X-Frame-Options", value: "SAMEORIGIN" },
  { key: "X-Content-Type-Options", value: "nosniff" },
  { key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
  { key: "Strict-Transport-Security", value: "max-age=63072000; includeSubDomains; preload" }
]

module.exports = {
  async headers() {
    return [{ source: "/(.*)", headers: securityHeaders }]
  }
}

5. Rate Limiting

// middleware.ts
export async function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith("/api/")) {
    const ip = request.ip ?? "anonymous"
    const key = `ratelimit:${ip}:${Math.floor(Date.now() / 60000)}`

    const requests = await redis.incr(key)
    if (requests === 1) await redis.expire(key, 60)

    if (requests > 60) {
      return Response.json(
        { error: "Too many requests" },
        { status: 429, headers: { "Retry-After": "60" } }
      )
    }
  }
}

6. Validasi Input yang Kuat

import { z } from "zod"

const RegisterSchema = z.object({
  email: z.string().email("Email tidak valid"),
  password: z.string()
    .min(8, "Password minimal 8 karakter")
    .regex(/[A-Z]/, "Harus mengandung huruf kapital")
    .regex(/[0-9]/, "Harus mengandung angka"),
  name: z.string().min(2).max(100).trim(),
})

export async function POST(req: Request) {
  const body = await req.json()
  const result = RegisterSchema.safeParse(body)

  if (!result.success) {
    return Response.json(
      { errors: result.error.flatten().fieldErrors },
      { status: 400 }
    )
  }

  const { email, password, name } = result.data
  // Lanjut proses dengan data yang sudah validated
}

Checklist Keamanan Sebelum Launch

  • Semua input divalidasi dengan Zod atau library serupa
  • Tidak ada SQL string concatenation
  • Semua endpoint API ada autentikasi dan otorisasi
  • Security headers terpasang
  • Rate limiting aktif
  • HTTPS dengan sertifikat valid
  • Password di-hash dengan bcrypt (cost factor >= 12)
  • Tidak ada secrets di kode — semua di environment variables
  • Dependencies di-update secara rutin (npm audit)
keamanan websecurityowaspxsssql injection2026

Newsletter Digital Uptime

Tips teknologi & bisnis mingguan

Bergabung dengan 2,500+ subscriber yang mendapatkan insight teknologi, tutorial development, dan tips bisnis digital langsung ke inbox mereka setiap minggu.

Tidak ada spam. Unsubscribe kapan saja.

Artikel Terkait

Kami menggunakan cookies untuk meningkatkan pengalaman Anda di website ini. Dengan melanjutkan, Anda menyetujui penggunaan cookies sesuai Kebijakan Privasi kami.