Dalam ekosistem pengembangan web modern berbasis Node.js dan TypeScript, pertukaran data antara antarmuka klien dan server backend hampir seluruhnya mengandalkan format JavaScript Object Notation (JSON). Kepraktisan parsing otomatis melalui middleware seperti express.json() membuat pengembang dapat langsung mengakses objek req.body dengan mudah di dalam fungsi kontroler.
Banyak insinyur perangkat lunak terlena oleh rasa aman semu yang dihadirkan oleh sistem pengetikan statis TypeScript. Mereka berasumsi bahwa mendefinisikan antarmuka (interface UpdateProfileDto) di tingkat kode sumber sudah cukup untuk menjamin keabsahan data yang masuk. Padahal, sistem tipe TypeScript sepenuhnya menguap saat kode dikompilasi menjadi berkas JavaScript murni. Mengabaikan validasi skema runtime yang ketat (runtime schema validation) pada setiap endpoint API publik adalah undangan terbuka bagi serangan siber yang mampu membajak logika server dan mengeksekusi kode berbahaya.
Anatomi Kerentanan Prototype Pollution dan Bencana Type Confusion
Ketiadaan filter skema yang ketat membuka ruang bagi dua vektor eksploitasi tingkat rendah yang sangat berbahaya:
- Manipulasi Rantai Pewarisan Prototipe (Prototype Pollution): Objek dalam runtime JavaScript mewarisi properti dari prototipe global
Object.prototype. Ketika aplikasi Anda menerima payload JSON mentah dan meneruskannya ke fungsi penggabungan objek rekursif (deep merge) atau pustaka kloning objek tanpa sanitasi, penyerang dapat menyuntikkan properti khusus seperti__proto__atauconstructor.prototype. Jika penyerang mengirimkan payload:
{
"__proto__": {
"isAdmin": true
}
}Properti isAdmin akan secara otomatis mencemari seluruh objek JavaScript baru yang dibuat di dalam memori server aplikasi. Akibatnya, pemeriksaan hak akses otorisasi (if (user.isAdmin)) pada pengguna biasa lain seketika bernilai benar (truthy), membuka celah eskalasi hak istimewa secara global tanpa perlu membobol kata sandi administrator.
- Kekacauan Tipe Data (Type Confusion) dan Injeksi NoSQL: Pengembang sering kali berasumsi bahwa parameter input selalu berupa string sederhana. Namun dalam protokol JSON, klien bebas mengirimkan array, objek bersarang, atau nilai boolean di properti mana pun. Pada sistem yang menggunakan basis data NoSQL seperti MongoDB, penyerang dapat mengganti string kata sandi dengan objek operator kueri:
{
"username": "admin",
"password": { "$gt": "" }
}Jika backend langsung meneruskan req.body.password ke fungsi pencarian kueri tanpa validasi tipe skema, kueri akan dievaluasi sebagai "cari dokumen dengan kata sandi lebih besar dari string kosong"—seketika membobol autentikasi admin tanpa pernah mengetahui kredensial aslinya.
- Injeksi Parameter Massal (Mass Assignment): Ketika pengguna mengirim properti ekstra yang tidak ada di antarmuka formulir (misalnya
role: "superadmin"ataubalance: 999999), ketiadaan filter skema yang memangkas properti tak dikenal membuat nilai-nilai berbahaya tersebut langsung tersimpan ke basis data melalui operasi pembaruan data otomatis (ORM mass-update).
Menegakkan Kontrak Skema Runtime yang Kokoh dan Disiplin
Membangun benteng pertahanan backend yang tangguh menuntut integrasi pustaka validasi runtime sebagai penjaga gerbang wajib:
- Gunakan Validator Skema Deklaratif Seperti Zod atau TypeBox: Wajibkan setiap endpoint API memvalidasi struktur data menggunakan pustaka validasi skema yang disiplin sebelum logika bisnis sempat dieksekusi:
import { z } from 'zod';
const UpdateUserSchema = z.object({
username: z.string().min(3).max(30).regex(/^[a-zA-Z0-9_]+$/),
email: z.string().email(),
age: z.number().int().positive().optional()
}).strict(); // Tolak properti tak dikenal!
app.post('/api/user/profile', (req, res) => {
const parseResult = UpdateUserSchema.safeParse(req.body);
if (!parseResult.success) {
return res.status(400).json({ errors: parseResult.error.format() });
}
// Data kini 100% aman dan bertipe bersih
const safeData = parseResult.data;
});- Kunci Objek dari Properti Prototipe Asing: Pastikan fungsi manipulasi objek menggunakan objek tanpa prototipe (
Object.create(null)) atau bekukan prototipe bawaan menggunakanObject.freeze(Object.prototype)saat inisialisasi server guna mematikan potensi polusi secara mutlak. - Tolak Secara Agresif Properti yang Tidak Terdaftar (Strip Unknown Keys): Jangan pernah mengizinkan klien mengirim properti di luar spesifikasi kontrak API. Konfigurasikan validator skema Anda untuk menghapus properti asing (strip unknown) atau langsung menolak permintaan dengan galat validasi ketat (HTTP 400 Bad Request), mencegah eksploitasi mass assignment sejak detik pertama payload tiba di server.
Integritas sistem perangkat lunak bermula dari rasa curiga yang sehat terhadap setiap bita data yang dikirimkan oleh pengguna; validasi skema runtime yang ketat adalah batas tegas antara aplikasi yang tangguh dan aplikasi yang tinggal menunggu waktu untuk dieksploitasi.



