FlawOpen

flawopen.com/Referensi/Injeksi NoSQL MongoDB: saat input mengubah kueri

Injeksi NoSQL MongoDB: saat input mengubah kueri

Panduan keamanan database

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

1

Endpoint mengharapkan nilai skalar

Kontrak API menetapkan username sebagai string, tetapi parser JSON juga dapat menghasilkan array, objek, boolean, dan null.

2

Aplikasi melewatkan validasi tipe

Handler memasukkan nilai hasil parsing langsung ke filter buatan server, sehingga objek tetap menjadi struktur kueri dan bukan string literal.

3

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.

4

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.

Ruang lingkup dan bukti

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

VULNERABLE — UNVALIDATED VALUE ENTERS FILTER
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);
  }
});
HARDENED — VALIDATE SHAPE, BUILD FILTER, VERIFY HASH
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

Sumber primer

Jelajahi panduan keamanan terkait:Buka direktori keamanan →
Lihat juga SQL Injection (CWE-89): cara kerja dan cara mencegahnya di setiap bahasa — flawopen.com Apakah format string berbahaya untuk ID numerik? Apa itu kueri terparameterisasi? Apakah Prisma $queryRaw aman dari SQL Injection? Apakah interpolasi string di Rails where() aman? Apakah Sequelize query() aman dari SQL Injection? Apakah SQLAlchemy text() aman dari SQL Injection?