Jebakan Vibe Coding: Top 6 Kerentanan React Tersembunyi
Artikel ini membahas proyek yang dibangun dengan React + Next.js App Router. Prinsip keamanan bersifat universal, tetapi contoh kode dan konfigurasi (
next.config.js,vercel.json) spesifik untuk tumpukan teknologi ini.
Anda meminta asisten AI untuk menulis sebuah komponen. Ia menulisnya. Berhasil. Pengujian berwarna hijau. Anda mengklik Merge.
Dan kemudian — kebocoran data, skor nol di Google PageSpeed, keluhan dari pengguna tunanetra, dan pertanyaan: “Mengapa kita tidak memiliki header keamanan?”.
Alat coding AI tidak mengetahui konteks produksi Anda. Bagi mereka, tidak ada perbedaan antara tutorial pemula dan aplikasi keuangan dengan pengguna sungguhan. Hasilnya — mereka menulis kode yang “berjalan”, tetapi secara diam-diam melanggar aturan dari OWASP Top 10.
Berikut adalah 6 kerentanan yang diam-diam disisipkan oleh asisten AI ke dalam kode React + Next.js. Dan cara menemukannya dalam 10 detik.
Fact-Check: Bagaimana AI Menghasilkan Kode yang Rentan
🔍 Bukti · Bias Pelatihan · Kebutaan Konteks
Menurut analisis GitHub terhadap repositori publik, persentase signifikan dari kebocoran keamanan dalam proyek React berasal dari pola umum yang ditemukan dalam data pelatihan—seperti menggunakan dangerouslySetInnerHTML tanpa sanitasi atau melakukan hardcoding variabel lingkungan di frontend.
Dalam pengujian internal kami di WebValid, asisten coding AI (Cursor, Copilot, ChatGPT) berhasil mengidentifikasi dan memperbaiki kerentanan hanya ketika diberikan laporan terstruktur dari pemindai eksternal. Ketika diminta untuk “meninjau kode ini untuk keamanan” tanpa konteks, model melewatkan 68% kebocoran arsitektural (seperti masalah bundle kunci API yang dijelaskan di bawah).
dangerouslySetInnerHTML Tanpa Sanitasi
🔴 Kritis · Pencurian sesi pengguna, denda GDPR · OWASP A03:2021 Injection
Asisten AI menyukai pola ini. Anda meminta untuk “merender HTML dari API” — mereka menulis:
// ❌ Kode AI Buruk
function UserBio({ bio }: { bio: string }) {
return <div dangerouslySetInnerHTML={{ __html: bio }} />;
}
Jika bio berasal dari pengguna — selamat, Anda terkena XSS. Penyerang akan menyisipkan <script>document.cookie</script> dan mencuri sesi pengguna Anda.
// ✅ Perbaikan: sanitasi melalui DOMPurify
import DOMPurify from "dompurify";
function UserBio({ bio }: { bio: string }) {
const sanitizedBio = DOMPurify.sanitize(bio);
return <div dangerouslySetInnerHTML={{ __html: sanitizedBio }} />;
}
Menurut pencarian repositori publik GitHub,
dangerouslySetInnerHTMLtanpa sanitasi ditemukan di ribuan proyek React. Asisten AI mereproduksi pola ini dari data pelatihan — tanpa menanyakan pertanyaan, “dari mana asal HTML ini?”
Kunci API dalam Client Bundle
🔴 Kritis · Kerugian finansial langsung · OWASP A02:2021 Cryptographic Failures
Dosa paling umum dari Vibe Coding. Asisten AI sering kali “memperbaiki” panggilan API sisi klien yang rusak dengan menambahkan awalan NEXT_PUBLIC_ ke kunci rahasia Anda. Ini membuat permintaan berhasil—tetapi juga memasukkan rahasia Anda langsung ke dalam bundle JavaScript publik, yang dapat dilihat oleh siapa saja melalui DevTools.
// ❌ Kode AI Buruk — kunci bocor ke dalam bundle JS
"use client";
const response = await fetch("https://api.openai.com/v1/chat/completions", {
headers: {
Authorization: `Bearer ${process.env.NEXT_PUBLIC_OPENAI_API_KEY}`, // ❌ BOCOR
},
});
Perbaikan: Pindahkan semua logika sensitif ke Server Action atau Route Handler di mana variabel lingkungan tetap berada di server secara ketat.
Untuk pembahasan mendalam tentang mekanisme kebocoran bundle dan cara menggunakan perlindungan canggih seperti Next.js Taint API, lihat panduan otoritatif kami: Panduan Kebocoran Kunci API.
Kurangnya Header Keamanan (CSP, X-Frame-Options, HSTS)
🟠 Tinggi · Clickjacking, pembajakan token melalui MitM · OWASP A05:2021 Security Misconfiguration
Asisten AI tidak mengonfigurasi header HTTP. Hal ini dapat dimaklumi — mereka menulis komponen, bukan konfigurasi server. Akibatnya, situs Anda dapat disematkan dalam <iframe> pada domain berbahaya, yang memungkinkan serangan clickjacking.
Untuk Next.js + Vercel, ada dua cara untuk menambahkan header:
Metode 1 — next.config.js (untuk self-hosting):
// ✅ 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: "Content-Security-Policy",
value: "default-src 'self'; script-src 'self';",
},
];
module.exports = {
async headers() {
return [{ source: "/(.*)", headers: securityHeaders }];
},
};
Metode 2 — vercel.json (untuk deployment Vercel — direkomendasikan):
{
"headers": [
{
"source": "/:path*",
"headers": [
{
"key": "Strict-Transport-Security",
"value": "max-age=63072000; includeSubDomains; preload"
},
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" }
]
}
]
}
WebValid memverifikasi keberadaan semua header ini dalam respons HTTP dalam satu kali pemindaian.
console.log Membocorkan Data Sensitif ke Produksi
🟡 Sedang · Kebocoran PII ke agregator log eksternal · OWASP A09:2021 Security Logging Failures
Selama sesi Vibe Coding, log debug secara alami tertinggal selama iterasi:
// ❌ Kode AI Buruk
async function loginUser(credentials: Credentials) {
console.log("Login attempt:", credentials); // kata sandi ada dalam log!
const user = await authService.login(credentials);
console.log("User logged in:", user); // token ada dalam log!
return user;
}
Jika log produksi Anda dikumpulkan dalam alat seperti Sentry, Datadog, atau Logtail — Anda baru saja mengirimkan kata sandi pengguna Anda ke layanan eksternal.
// ✅ Perbaikan: logging terstruktur hanya untuk data non-sensitif
import { createLogger } from "@your-scope/logger";
const logger = createLogger({ scope: "AuthService" });
async function loginUser(credentials: Credentials) {
logger.info("Login attempt", { email: credentials.email }); // hanya email
const user = await authService.login(credentials);
logger.info("Login successful", { userId: user.id }); // hanya ID
return user;
}
Semantik dan ARIA yang Rusak
🟡 Sedang · Kehilangan trafik SEO, pelanggaran kepatuhan ADA · Pelanggaran Aksesibilitas (WCAG 2.1)
Asisten AI membuat semuanya dapat diklik dengan menempatkan handler onClick pada <div>. Ini cepat dan berfungsi secara visual — tetapi mematikan kemampuan perayapan (crawlability) dan aksesibilitas:
// ❌ Kode AI Buruk
function ProductCard({ product }: { product: Product }) {
return (
<div onClick={() => navigate(`/products/${product.id}`)}>
<div>{product.name}</div>
<div>{product.price}</div>
</div>
);
}
Masalahnya:
- Pembaca layar tidak mengenali elemen interaktif — pengguna tunanetra tidak dapat mencapai produk.
- Googlebot tidak menyusun grafik tautan melalui
onClick— hanya melalui<a href>. - Aliran PageRank internal antar halaman hilang.
// ✅ Perbaikan: HTML semantik
function ProductCard({ product }: { product: Product }) {
return (
<article>
<a href={`/products/${product.id}`}>
<h2>{product.name}</h2>
<span>{product.price} $</span>
</a>
</article>
);
}
Server Actions Tanpa Otorisasi
🔴 Kritis · Menjalankan tindakan atas nama pengguna mana pun · OWASP A01:2021 Broken Access Control
Asisten AI sering kali menghasilkan Server Actions — tetapi mengabaikan untuk menyertakan pemeriksaan otorisasi.
// ❌ Kode AI Buruk
"use server";
export async function deleteAccount(userId: string) {
await db.user.delete({ where: { id: userId } });
}
Siapa pun dapat mengirimkan permintaan POST dan menghapus akun orang lain.
// ✅ Perbaikan: pemeriksaan otorisasi internal di dalam tindakan
"use server";
import { getServerSession } from "next-auth";
export async function deleteAccount(userId: string) {
const session = await getServerSession();
if (!session || session.user.id !== userId) {
throw new Error("Unauthorized");
}
await db.user.delete({ where: { id: userId } });
}
Cara Menemukan Semua dari 6 Kerentanan dalam 10 Detik
Anda dapat meninjau kode secara manual — atau menghabiskan satu hari untuk audit penuh. Namun ada cara yang lebih cepat:
- Jalankan proyek lokal Anda melalui ngrok untuk mendapatkan URL publik.
- Tempelkan ke WebValid.
- Terima
ai-fix-promptyang siap pakai di Markdown — tempelkan ke asisten AI Anda dan perbaiki semuanya dalam 2 menit.
Daftar Periksa Keamanan Generatif 6 Poin Anda
- Penanganan Input: Apakah AI menggunakan
dangerouslySetInnerHTML? - Variabel Lingkungan: Apakah ada kunci rahasia?
- Header Keamanan: Apakah Anda sudah mengonfigurasi
vercel.json? - Eksfiltrasi Data: Apakah ada pernyataan
console.loglangsung? - SEO Interaktif: Periksa elemen yang dapat diklik.
- Otorisasi Tindakan: Apakah setiap tindakan
'use server'dimulai dengan pemeriksaan otorisasi?
→ Uji proyek Anda secara gratis di WebValid
Dokumentasi Resmi
Security
Next.js
- Next.js: Security Headers
- Next.js: Environment Variables
- Next.js: Taint API
- Next.js: Server Actions Security