// body: { "email": "victim@example.com", "token": { "$ne": null } }
const user = await db.collection("users").findOne({
email: req.body.email,
resetToken: req.body.token,
});
if (user) allowPasswordReset(user);
The filter matches the victim whenever they have any reset token, so the check passes; validate that
token is a string before queryingThe filter matches the victim if they have any reset token, so the check passes. JSON bodies can contain objects. An object with a $ne key becomes a MongoDB query operator. This turns an equality check into "not equal to null".
To prevent it, use schema validation that requires token to be a string, or remove keys that start with $.
"Nothing, because MongoDB doesn't execute SQL" is the tempting wrong answer. Operator injection is its own kind of injection, and it doesn't need SQL.
Read more