The $where
operator in MongoDB is a feature which is best avoided. Its performance is abysmal, and not just because it doesn't benefit from indexes. Almost every common use-case can be solved much more efficiently with a common find-query or aggregation, especially one as trivial as this. But this is security stackexchange, not stackoverflow, so let's focus on the security implications.
The $where
statement passes a javascript code snippet to the database which the database will then execute once for each document in the collection. Thankfully this script has no access to the db
object and other dangerous shell functions and it works on copies of the documents, so the attacker can at least not change the database content like with many SQL injections. But it is for example vulnerable to attacks where the attacker wants to return other results than intended.
Let's make up an example. Let's say we have a blog. Our blog has lots of articles which can be read public, but we also have some private articles which are for our internal use and not supposed to be published. So we have a field hidden
in our documents which can be true
or false
depending on whether or not our visitors are supposed to see the article. Our MongoDB query to get a list of all articles in a certain category for displaying it to the website visitor looks like this:
db.articles.find({"$where": "this.hidden == false && this.category == '"+category+"'" });
That should make sure nobody looks at our hidden articles. Or does it? When the user controls the category
-variable, they can set it to this string:
'; return '' == '
The resulting Javascript snippet which gets send to the database is this:
this.hidden == false && this.category == ''; return '' == ''
When you have a javascript snippet with multiple commands separated by ;
, they will be executed as a function and a return
statement is needed to determine which value will be passed back to the caller. This function will always return true. That means the user will also see all articles in our collection, including those which are supposed to be hidden.