Its a misconception amongst some PHP programmers that because MongoDB doesn’t use SQL (all queries are passed in as either BSON or PHP objects which have been converted into BSON) it isn’t vulnerable to SQL injection. It is pretty easy to show that if your lazy and complacent when you code you can leave yourself just as vulnerable to attack.
Lets assume we have a table of users with a username and password field. In MySQL you’d be asking for trouble if in your authentication function you did the something along the lines of the following:
if (mysql_query(“SELECT * FROM users WHERE username=’$_GET['username']‘ AND password=’” . $_GET['password'] . “’”)) {
do_auth();
}
And someone passed in
‘ OR ‘1′=’1
into your password field. If you simply checked the response and authenticated the user based on if a row was received from the MySQL Database the user would authenticate as the $_GET['username'] every time. The correct approach would be to sanitize your $_GET parameters before you pass them into MySQL.
In MongoDB you might be tempted to do something like
if ($result = $mongo->test->users->findone(array(”username” => $_GET['username'], “password” => $_GET['password']))) {
do_login();
}
No query language no SQL injection right? Wrong. Epic fail. Don’t forget in PHP when you append [] to a $_GET['variable'] it turns into an array within php.
http://woot.php?variable[]=hello
$_GET['variable'] is now a PHP array(0 => ‘hello’). We can even assign the key of the array like this
http://woot.php?variable[ne]=hello
Now $_GET['variable'] is a PHP with array with a key array(’ne’ =>’hello’). When you pass this to mongo db as your password paramater it evaluates to “Password does not equal ‘hello’” which will pass every time.
What can you do? Sanitise your input. Don’t allow multi dimensional arrays to be passed as a input parameters to mongo. Surprisingly there isn’t a function built into the mongodb pecl extension to do this, With more and more large sites turning to MongoDB its only going to be a matter of time before a large website is found to be vulnerable to this type of attack.
