mongoDB.md
Last updated
Last updated
/!\ IMPORTANT /!\
Note that NoSQL injections using db
are only available in versions of MongoDB prior to 2.4 (released in March 2013). Since this version, the global variable db
was completely removed.
On MongoDB 2.4 and subsequent versions, NoSQL injection can only be leveraged to:
bypass filter, such as authentication mechanism
conduct a Denial of Service of the server
MongoDB stores data as BSON documents, i.e. data records, in collections; the collections in databases. A record in MongoDB is a document, which is a data structure composed of field and value pairs. MongoDB documents are similar to JSON objects. The values of fields may include other documents, arrays, and arrays of documents.
CRUD Operations
The CRUD operations allows to create, read, update, and delete documents.
Read operations
Function | Description | Example |
---|---|---|
Create operations
If the collection does not currently exist, insert operations will create the collection.
Function | Description | Example |
---|---|---|
Update operations
Delete operations
Operators
Logical operators
Comparison operators
Evaluation operators
Two ways can be used to detect user inputs being passed un-sanitized in a MongoDB operation:
special characters that would trigger a database error
using server-side JavaScript execution for time-based detection
Authentication bypass
MongoDB authentication bypass can be achieved using the $ne
or $gt
operators.
While the parameters can be left blank for the injection, a pre check on the supplied data may require values to be provided.
Authentication extract password
An injection in a login form can be used to retrieve an user clear text password. The $regex
evaluation operator can be used to determine the password length and the password itself using letter by letter matching.
The authentication will fail as soon as the condition specified by the regex evaluate to false.
$where
tautology
The $where
operator can be used to make conditional statements such as the one in the following code:
Conditions in $where
clause could be bypassed using the following injections:
NoSQL injection using db
Note that, as specified above, blind NoSQL injections are not possible on MongoDB 2.4 and subsequent versions. Prior to this version, the global db
variable could be referenced to and used in injection.
The injections used below are blind Boolean injections. The web server comportment should vary depending on whether the query evaluated to true
or false
.
Different injections' syntax may work:
Collections length and names
The Metasploit module auxiliary/gather/mongodb_js_inject_collection_enum
can be used to enumerate the collections available via boolean injections.
The following operations can be used to retrieve the collections length and names manually:
Collections enumeration
To enumerate a collection's documents:
$where
Denial of Service
An injection in a $where
close could be leveraged to realize a Denial of Service by exhausting the server resources using:
Function | Description | Example |
---|---|---|
Function | Description | Example |
---|---|---|
Operator | Description |
---|---|
Operator | Description |
---|---|
Operator | Description |
---|---|
db.collection.find()
Retrieves documents from a collection
db.users.find( { username: req.body.username, password: req.body.password } )
db.collection.findOne
Returns one document that satisfies the specified query criteria in the collection
db.users.findOne( { "username": req.body.username, "password": req.body.password } )
db.collection.insertOne
Deprecated in major driver, inserts a document or documents into a collection
See db.collection.insertOne() and db.collection.insertMany() below
db.collection.insertOne()
New in version 3.2, inserts a document into a collection
db.products.insertOne( { "item": "card", "qty": 15 } )
db.collection.insertMany()
New in version 3.2, inserts multiple documents into a collection
db.products.insertMany( [ { "item": "card", "qty": 15 }, { "item": "enveloppe", "qty": 20 }, { "item": "stamps" , "qty": 30 } ] );
db.collection.update()
Deprecated in major driver, modifies an existing document or documents in a collection
See db.collection.updateOne() and db.collection.updateMany() below
db.collection.updateOne()
New in version 3.2, modifies the first matching document in the collection that matches the filter
db.products.updateOne( { "item" : "card" }, { $set: { "qty" : 25 } } )
db.collection.updateMany()
New in version 3.2, updates multiple documents within the collection based on the filter
db.products.updateMany( { "qty": { $lt: 5 } }, { $set: { "lowStock": true } } )
db.collection.replaceOne()
New in version 3.2, replaces a single document within the collection based on the filter
db.products.replaceOne( { "item": "enveloppe" }, { "item": "envelope", "qty": 20 } )
db.collection.remove()
Deprecated in major driver, removes a single or multiple documents from a collection
db.products.remove( { "qty": { $lte: 20 } } ) # Just one db.products.remove( { "qty": { $lte: 20 } }, true ) # Just one after version 2.6 db.products.remove( { "qty": { $lte: 20 } }, { "justOne": true } )
db.collection.deleteOne()
New in version 3.2, removes a single document from a collection
db.collection.deleteOne( { "item": "envelope" } )
db.collection.deleteMany()
New in version 3.2, removes all documents that match the filter from a collection
db.collection.deleteMany( { "qty": { $lte: 0 } } )
$or
Joins query clauses with a logical OR returns all documents that match the conditions of either clause
$and
Joins query clauses with a logical AND returns all documents that match the conditions of both clauses
$not
Inverts the effect of a query expression and returns documents that do not match the query expression
$nor
Joins query clauses with a logical NOR returns all documents that fail to match both clauses
$eq
Matches values that are equal to a specified value
$ne
Matches all values that are not equal to a specified value
$gt
Matches values that are greater than a specified value
$gte
Matches values that are greater than or equal to a specified value
$lt
Matches values that are less than a specified value
$lte
Matches values that are less than or equal to a specified value
$nin
Matches none of the values specified in an array
$in
Matches any of the values specified in an array
$expr
Allows use of aggregation expressions within the query language
$jsonSchema
Validate documents against the given JSON Schema
$mod
Performs a modulo operation on the value of a field and selects documents with a specified result
$regex
Selects documents where values match a specified regular expression
$text
Performs text search
$where
Matches documents that satisfy a JavaScript expression