0
I’m using mongodb with Mongoose in nodejs, I have my schema like this:
const UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true,
require: true
},
balances: {
dolar: {
manualBalance: {
type: Number,
select: false
},
paidBalance: {
type: Number,
select: false
}
}
}
});
So I try to do this:
router.post('/get_user_balance', async (req, res) => {
const { username } = req.body;
User.findOneAndUpdate({ username: username }, { $set: { balances: {dolar: {manualBalance: '1.50' }}}});
const balances = await User.findOne({ username }).select('+balances.dolar.manualBalance');
console.log(balances);
}
and receive from nodejs the error:
(node:22826) UnhandledPromiseRejectionWarning: MongoError: Projection cannot have a mix of inclusion and exclusion.
I believe it’s .select('+balances.dolar.manualBalance');
that is wrong. So I also tried without select and removed the "select: false" from my schema, retained the database and created a user again, and received from the console.log only the username, instead of also receiving the field "balances".
{
_id: 5ab00b7a92fe402bb85f407f,
username: 'Jerildo',
__v: 0
}
I’m registering users like this:
const user = await User.create(req.body);
where req.body is : {username: "jerildo"}
I know it must be simple thing that I am wrong for not knowing so well the mongodb or the Mongoose, always worked with Redis, this is new for me. Then I ask for a force here.
In production do not use user input directly to the database... Select, escape strings and if possible (and highly recommended) disable javascript execution in the database. In the configuration file set: security -> javascriptEnabled: false
– Lauro Moraes
@Lauromoraes, I appreciate the information, but it’s not in production, I haven’t looked at security yet, but I’ll be studying security for mongodb later. I first need to learn how to use it, and as you can see in the question, I’m not sure XD
– PerduGames
I don’t know why you’re wearing
async
...could simply chain. Usingasync
"unbound" should wait (await) on first (findOneAndUpdate) and second (findOne) request. You must pass the argumentnew: true
infindOneAndUpdate()
if you want to return the modified document. I will edit my reply.– Lauro Moraes
I am using async because my API uses async. findOneAndUpdate() only returns one document. But let’s ignore findOneAndUpdate(), just the other findOnde(), it shouldn’t return me {username: "jerildo", Balances:{dolar: {manualBalance: 0}}} ? because returns me only the username?
– PerduGames
I am editing my answer with an example that I tested locally... this returning me both user and balance. I finish soon
– Lauro Moraes
Could you recommend me some module to handle the "escape strings"? Sanitize for what I saw is just reject case
(/^\$/.test(mystring))
be it true , so the user will not be able to inject using $ne for example, certain?– PerduGames
https://www.npmjs.com/package/express-mongo-sanitize
– Lauro Moraes
It was exactly this module I saw, just does this check (/$/.test(mystring)) even kkkkk and to handle the "escape strings"?
– PerduGames
This module not only checks, it accepts opposites and can delete "injection" entries or even replace pre-defined "malicious" entries. See the source code on Github: https://github.com/fiznool/express-mongo-sanitize/blob/master/index.js . But the best Nosql injection prevention in Mongodb is (and remains) disabling Javascript in the database
– Lauro Moraes
I mistook it for Mongo-Sanitize, I’ll read it here.
– PerduGames
@Lauromoraes I read here https://zanon.io/posts/nosql-injection-in-mongodb that Mongoose does not need to sanitize, it already converts to string when you specify the type: String. Thus avoiding the injection.
– PerduGames
You can also check here http://mongoosejs.com/docs/validation.html about Mongoose convert to string.
– PerduGames