NoSQL Injection in Meteor.js Application

Those who were not able to attend our 2nd Meteor Ho Chi Minh meetup at July 9th could find all about NoSQL Injection in Meteor.js Application — one of the main topics of the meetup — in this blog.

Before digging into every facet of this post, you are required to have a fairly good background of Meteor and MongoDB, which is the most widely used NOSQL database. If you are a Meteor-novice, no worries! You can discover more about this full-stack JavaScript platform for developing single-page, real time web and mobile apps at Meteor.com

Now, are you ready to get what you missed at our Meetup?

SQL INJECTION

SQL Injection is defined as a code injection technique, used to attack data-driven applications, in which nefarious SQL statement are inserted into an entry field for execution. (Source: Wikipedia)

In other words, SQL injection is a technique where malicious users inject SQL commands into an SQL statement to change it and compromises the security of a web application with SQL database.

There are 4 common forms of technical implementations of SQL injection:

  • Incorrectly Filtered Escape Characters with this line of code:
statement = "SELECT*FROMusersWHERE name = '" + userName + "';"
  • Incorrectly Type Handling:
statement := "SELECT*FROMuserinfoWHEREid=" + a_variable + ";"
  • Blind SQL Injection:
SELECT*FROMbookreviewsWHEREID='Value(ID)';

Second order SQL injection

I am going to give you an example of Incorrectly Filtered Character. Here I want to get a user data with username Peter and password “$PWQ”, the query looks something like this:

// query
SELECT * FROMusers
WHERE username='peter’
AND (password=('$PWD'))

If I use a “weird” input, for example:

// input
' OR '1'='1’

The result query is:

// result
SELECT * FROM users
WHERE username='peter' AND (password='' OR '1'='1')

As you can see, the condition (password=” OR ‘1’=’1′) is always true. That’s why the result query is always successful. By this way, attackers can get any arbitrary user data, given the username.

NOSQL INJECTION

Now, although NoSQL is still a popular attacking technique, it’s no longer as widespread as it used to be. Many modern apps use NoSQL databases such as MongoDB for its simplicity and speed. Unlike SQL in which queries use STRINGs as the control mechanism, NoSQL queries use OBJECTs instead. With NoSQL Injection, instead of injecting STRINGS as parameters, attackers use SUB-OBJECTs as parameters to inject database queries.

The SQL statement that we used above to query the user login details will be written like this in MongoDB:

db.users.find({username: username, password: password});

As mentioned before, attackers can use subobjects as parameters to inject to NoSQL database queries, for example:

db.users.find({
username: “peter”,
password: { $gt: “” }
})

In the above query, the $gt operators stands for “greater than”. The password is not validated to ensure that it is string. Therefore, when the JSON document is deserialized, that field may contain anything but string that can be used to manipulate the structure of the query. You can get that what the query does is comparing the password of “peter” with an empty string, so this condition is always true.

In MongoDB, there’re many similar operators, like $gt that attackers can take advantage of, such as: $gte (greater than or equal to), $lt (less than), $lte (less than or equal to), $ne (not equal to), $nin (matches none of the values specified in an array), etc.

NOSQL INJECTION IN METEOR APPLICATION

Here comes the Meteor part. Typically the default data layer of Meteor applications in MongoDB, which puts Meteor apps in the risk of being exploited using the NoSQL Injection technique. Let’s get into one demo application for testing NoSQL Injection: meteor-shop. you can clone the app from https://github.com/sonlexqt/meteor-shop. This web application is written in Meteor. Please follow the instruction in README.md file for how to setup and run the app in your local machine.

In the scope of Meteor, attackers usually take advantage of publication functions and methods. For example, you can see that in the publication.js file we have this publication function:

// Get the products, filtered by their vendor
Meteor.publish("products-by-vendor", function(slug){
return Products.find({"vendor.slug" : slug})
});

We (as developer) are expecting the slug information to be a string, but haven’t check for that condition. So whatever input can be injected into this function, which makes it vulnerable to NoSQL Injection. For example. an attackers can do this (in browser console) to get all the documents in the Products collections:

Meteor.subscribe(“products-by-vendor”, { $ne: null })
Products.find().fetch() // Now all products in the database are shown !

You can take a look at the server/publication.js file and meetup.js file. Those files contain some examples to help you play around with NoSQL in the demo app.

SOLUTION TO THE PROBLEM

Read full article

A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.