I'm using the Mongoose ODM wrapper for NodeJS and I'm concerned about injection attacks. Let's assume I have the following schema:
const UserSchema = new mongoose.Schema({ userName: String, password: String });
If I were to perform a login request that looks like the following:
router.post('/login', (request, response) => {
const userName = request.body.userName;
const password = request.body.password;
User.findOne({ userName: userName }, function (error, user) {
// ... check password, other logic
});
});
I would be open to an injection attack with the following JSON payload which will always find a user:
{
"email": { "$gte": "" },
"password": { "$gte": "" }
}
I'm not concerned about the password as it is hashed if a user is found which prevents any actual log in but I want to make sure my input is sanitized so that an attacker wouldn't even make it to that point.
I'm aware of the mongo-sanitize NPM package referenced in a similar StackOverflow post which appears to remove all JSON keys that begin with '$'. I plan on using this anyway but I will never allow the user to submit raw, unparsed JSON. Is it good practice in that case to just call toString() on the userName assuming I do the correct null
checks?
const userName = request.body.userName.toString();
That would eliminate the query from being executed but it doesn't feel very secure. I assume the following is a better approach as it tries to convert userName
to a String
:
User.findOne({ userName: { "$eq": userName } }, function (error, user) {
// ... other logic
});
I can't find anything concerning this in the in the Model.findOne() documentation which leads me to believe I'm overlooking something.
Any insight would be appreciated.
Other References:
While you could use
$eq
to ensure an equality comparison is used in the query, your express route handler is a better place to perform request format validation.A valid
POST /login
should haveuserName
andpassword
string fields in the body of the request. If not, it should be rejected before it even gets to Mongoose.