flawopen.com/Referensi/Injeksi NoSQL MongoDB: saat input mengubah kueri
Injeksi NoSQL MongoDB: saat input mengubah kueri
MongoDB tidak menjalankan SQL, jadi penggabungan string SQL bukan masalahnya. Injeksi NoSQL tetap dapat terjadi jika aplikasi menerima objek bertingkat tak tepercaya saat mengharapkan nilai skalar lalu meneruskannya ke filter MongoDB. Ini adalah kesalahan validasi input aplikasi, bukan CVE server MongoDB.
Sederhananya: nilai berubah menjadi aturan
Bayangkan formulir meminta nama, tetapi petugas menerima seluruh rangkaian instruksi pengarsipan di kolom itu. Database lalu mengikuti instruksi alih-alih membandingkan satu nama. Validasi tipe nilai yang diharapkan dan susun sendiri aturan pencariannya.
Batas kepercayaan: dari JSON permintaan ke filter MongoDB
- Filter kueri
- Dokumen BSON yang ditafsirkan MongoDB sebagai perbandingan field dan, jika disertakan secara eksplisit, operator kueri.
- Injeksi operator
- Aplikasi meneruskan struktur yang dikendalikan pengguna pada posisi yang seharusnya menerima satu nilai literal.
- Validasi skalar
- Memeriksa tipe, panjang, dan format yang diizinkan sebelum input memengaruhi operasi database.
- Proyeksi
- Daftar field hasil kueri yang dipilih server untuk membatasi paparan data yang tidak disengaja.
Bagaimana kegagalan terjadi
Endpoint mengharapkan nilai skalar
Kontrak API menetapkan username sebagai string, tetapi parser JSON juga dapat menghasilkan array, objek, boolean, dan null.
Aplikasi melewatkan validasi tipe
Handler memasukkan nilai hasil parsing langsung ke filter buatan server, sehingga objek tetap menjadi struktur kueri dan bukan string literal.
MongoDB mengevaluasi struktur tersebut
Jika dokumen bertingkat berisi operator kueri, predikat dapat berbeda dari perbandingan nilai tepat yang dimaksud. Rekaman terdampak bergantung pada kueri dan pemeriksaan otorisasi aplikasi.
Respons menentukan paparan
Field dan jumlah rekaman yang dikembalikan bergantung pada proyeksi, perilaku endpoint, dan hak akun database. Ini sendiri tidak membuktikan bypass autentikasi atau akses ke seluruh database.
Panduan resmi driver MongoDB menjelaskan batas ini ketika endpoint mengubah JSON tanpa validasi menjadi BSON lalu menggunakannya sebagai filter. Panduan ini memodelkan kegagalan pada tingkat aplikasi. Ini tidak menyatakan semua deployment MongoDB rentan, tidak menyebut CVE server, dan tidak memberikan resep bypass autentikasi.
Pola rentan dan diperkuat di Node.js
app.post("/users/lookup", async (req, res, next) => {
try {
// The route expects a string, but req.body.username is untrusted JSON.
const user = await users.findOne({ username: req.body.username });
res.json(user ? { username: user.username } : null);
} catch (error) {
next(error);
}
});
const loginSchema = z.object({
username: z.string().trim().min(1).max(128),
password: z.string().min(1).max(1024)
}).strict();
app.post("/login", async (req, res, next) => {
try {
const parsed = loginSchema.safeParse(req.body);
if (!parsed.success) return res.sendStatus(400);
const { username, password } = parsed.data;
// The application owns the filter key; input supplies only a string value.
const user = await users.findOne(
{ username },
{ projection: { _id: 1, username: 1, passwordHash: 1 } }
);
const passwordMatches = user &&
await argon2.verify(user.passwordHash, password);
if (!passwordMatches) return res.sendStatus(401);
return res.sendStatus(204); // Session creation is application-specific.
} catch (error) {
next(error);
}
});
Alur yang diperkuat menolak field non-string sebelum mengakses database, tidak menerima objek filter dari klien, menyusun kunci filter tetap di kode aplikasi, hanya mengembalikan field yang dipilih, dan memverifikasi hash kata sandi setelah mencari pengguna. Contoh ini mengasumsikan z adalah Zod, users adalah koleksi MongoDB, dan argon2 adalah pustaka hash kata sandi yang telah dikonfigurasi; pembuatan sesi sengaja tidak dicakup.
Pemeriksaan untuk memverifikasi perbaikan
- ✓Kirim string biasa dan pastikan handler hanya mencari field tepat yang ditentukan aplikasi.
- ✓Kirim objek, array, angka, boolean, null, field yang hilang, string terlalu panjang, dan properti tak dikenal; pastikan schema menolak bentuk tak valid sebelum MongoDB dipanggil.
- ✓Pastikan panggilan database menerima filter buatan server, bukan filter dari klien atau fragmen JSON mentah.
- ✓Pastikan proyeksi mengecualikan hash kata sandi dan field lain yang tidak terkait, serta peran database hanya memiliki izin koleksi yang diperlukan.
- ✓Hash kata sandi dengan Argon2id atau bcrypt dan verifikasi hash di aplikasi; jangan pernah memakai kata sandi kiriman sebagai filter MongoDB.
Sumber primer
- MongoDB — praktik terbaik pustaka klien: validasi input tak tepercaya sebelum mengubah JSON menjadi BSON
- OWASP — lembar contekan keamanan NoSQL
- MongoDB — membuat filter kueri (driver C#): validasi adalah tanggung jawab aplikasi