Its a common misconception that as MongoDB does not use SQL it is not vulnerable to SQL injection attacks. PHP uses objects rather than SQL to pass queries to the MongoDB server; for example the following script selects an item form MongoDB where the username equals ‘bob’ and the password equals ‘password’.
$collection->find(array(
"username"=>$_GET['username'],
"passwd"=>$_GET['passwd']
));
This is equivalent to the SQL syntax
mysql_query("SELECT * FROM collectionWHERE username=" . $_GET['username'] . ",AND passwd=" .$_GET['passwd'])
In a normal SQL injection attack we can replace either of the two input parameters with a string such that the SQL query always returns true. e.g.
login.php?username=admin&passwd=" OR 1 --
That wont work with MongoDB; however if we can pass in an object to the PHP MongoDB driver we could alter the query in a similar fashion. Luckily PHP provides us with a way to pass objects as GET or POST parameters:
login.php?username=admin&passwd[$ne]=1
This creates the MongoDB query
$collection->find(array("username"=>"admin","passwd"=>array("$ne"=> 1)));
Which is the equivalent to the following SQL statement which, unless the password is “1″ will always return true.
mysql_query("SELECT * FROM collectionWHERE username="admin",AND passwd!=1
The solution is to ensure your variables are properly typed before they are passed into the MongoDB driver. The following code is not vulnerable to MongoDB injection:
$collection->find(array("username"=> (string)$_GET['username'],"passwd"=> (string)$_GET['passwd']));