2

I'm using MongoDB 4.2 with Express > 4.

I'm trying to execute a NoSQL Injection using node.js. This is the .ejs code of a form with username and password:

 <body> <form action="/login_db/login_db" method="POST" > <input placeholder="name" name="name"> </br> <input placeholder="password" name="password"> </br> <input type="submit" value="submit" id="submit"> </form> </body> 

I have a local MongoDB Database with user that are allowed to get access through the db. This is the .js code:

const MongoClient = require("mongodb").MongoClient; const ObjectID = require('mongodb').ObjectID; const dbname = "mydb"; const url = "mongodb://localhost:27017"; const mongoOptions = {useNewUrlParser : true}; const state = { db : null }; const connect = (cb) =>{ if(state.db) cb(); else{ MongoClient.connect(url,mongoOptions,(err,client)=>{ if(err) cb(err); else{ state.db = client.db(dbname); cb(); } }); } } const getPrimaryKey = (_id)=>{ return ObjectID(_id); } const getDB = ()=>{ return state.db; } module.exports = {getDB,connect,getPrimaryKey}; 

And this is the .js login_db-route.js:

"use strict" const router = require('express').Router(); const db = require("../db"); const mongoose = require('mongoose'); const passport = require('passport'); const express = require('express'); const collection = "amministrazione"; const app = express() const path = require('path'); var bodyParser = require('body-parser') router.get('/login_db', function(req,res){ console.log('login request'); var cursor = db.getDB().collection(collection).find().toArray(function(err, results) { res.render('login_db.ejs', {quotes: results, user: req.user}); }); }); router.post('/login_db', function (req, res) { console.log('login post request'); var name = req.body.name; var password = req.body.password; db.getDB().collection(collection).findOne({"name" : name, "password" : password}, (err, result) =>{ if(result == null || result.length == 0){ console.log('user not found '+ err); return res.render('login_db.ejs',{user: req.user}); } console.log('User found' + result); db.getDB().collection(collection).find().toArray((err, result)=>{ if(err) return console.log(err) res.render('book.ejs', {quotes:result,user: req.user, flag: true}); }) }) }); module.exports = router; 

The code that i wrote is vulnerable to nosql injection, but when i try to insert into the form a MongoDB Payload, such as:

{ $gt : "a" } { $gt : "a" } 

i can't have login success. Where is the problem? Is there a way not to consider the " ?

Thanks to anyone who helped me.

9
  • do you mean username = "{ $gt : "a" }" to check nosql injection? Commented Oct 4, 2019 at 20:05
  • if you log your payload by console.log, you can see that " is changed to \". Commented Oct 4, 2019 at 20:08
  • Yes, mongodb receive "{ $gt : "a"}" instead of { $gt: "a"} due to the JavaScript interpretation of parameters as primitive strings Commented Oct 4, 2019 at 20:12
  • I tried to do console.log of payload but the " remain " Commented Oct 4, 2019 at 20:14
  • 1
    Do you want to add " to mongodb? Otherwise, do you want to check " on node.js side? Commented Oct 4, 2019 at 20:14

1 Answer 1

3

This is your code.

var name = req.body.name; var password = req.body.password; db.getDB().collection(collection).findOne({"name" : name, "password" : password}); 

If you pass those parameters, the mongodb query will be like this.

db.getDB().collection(collection).findOne({"name" : "{ $gt : \"a\" }", "password" : "{ $gt : \"a\" }"}); 

If you want to pass those parameters as query but not string, you can add some code like this.

var name = req.body.name; var password = req.body.password; try { name = JSON.parse(name); } catch (e){} try { password = JSON.parse(password); } catch (e){} db.getDB().collection(collection).findOne({"name" : name, "password" : password }); 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.