NoSQL injection: MongoDB sorgularını istekten yeniden yazmak

NoSQL veritabanları SQL ayrıştırmaz ama yine de yapıyı yorumlar. String beklediğin yere nesne gönderen ya da metni bir $where ifadesinin içine düşen bir istek, sorgunun anlamını değiştirir.

Örnek

Zafiyetli
// $where runs JavaScript inside MongoDB
allocations.find({
  $where: `this.userId == ${userId} && this.stocks > '${req.query.threshold}'`
});

// {"password": {"$ne": null}} matches any user
users.findOne({ user: req.body.user, password: req.body.password });
Güvenli
const threshold = Number.parseInt(req.query.threshold, 10);
if (!(threshold >= 0 && threshold <= 99)) return res.sendStatus(400);
allocations.find({ userId, stocks: { $gt: threshold } });

users.findOne({ user: String(req.body.user) });
// then compare the password hash with bcrypt.compare

Nasıl oluşur

İki biçimi var. $where, MongoDB'nin her belge için çalıştırdığı JavaScript'i alır; 1'; return true; ' gibi bir değer her şeyi döndürür, sonsuz bir döngü sunucuyu kilitleyebilir. Operatör injection'ı daha sessizdir: gövde ayrıştırıcılar password[$ne]= değerini {"$ne": ""} nesnesine çevirir ve istek değerini olduğu gibi koyan bir giriş sorgusu her hesapla eşleşir.

Nasıl düzeltilir

İstek verisini düz değer olarak tut.

  • $where kullanma; koşulları sorgu operatörleriyle yaz
  • Sorgudan önce değerleri beklediğin türe çevir (String, Number)
  • Mongoose sanitizeFilter'ı aç veya girdiden $ ile başlayan anahtarları temizle
  • Kullanıcıyı adıyla bul, sonra parola hash'ini ayrıca doğrula

RepoVerse bunu nasıl bulur

  • Yüksekİstek girdisi MongoDB `$where` ifadesinin içinde çalışıyor

    `$where`, veritabanının çalıştırdığı JavaScript'tir. Özel bir değer tüm belgeleri döndürebilir (`1'; return true; '`) veya sunucuyu kilitleyebilir (`';while(true){}'`).

    veri akışı · CWE-943

  • Ortaİstek değeri doğrudan MongoDB filtresinde kullanılıyor

    Gövde ayrıştırıcı nesne kabul ediyorsa, o alana gönderilen `{"$ne": null}` veya `{"$gt": ""}` her belgeyle eşleşir — klasik giriş atlatma.

    veri akışı · CWE-943

Sorular

MongoDB'de SQL olmadığı için injection olmaz mı?
Hayır. $where JavaScript çalıştırır ve istekten gelen sorgu operatörleri hangi belgelerin eşleşeceğini değiştirir. İkisi de CWE-943 olarak sınıflandırılır.
RepoVerse NoSQL injection'ı nasıl tespit ediyor?
İstek girdisini $where string'lerine kadar — veri erişim katmanına giden dosyalar arası yollar dahil — izler ve operatör nesnesi taşıyabilecek, doğrudan filtre değeri olarak kullanılan istek değerlerini işaretler.

İlgili

Güncellendi 2026-10-11