Estimate project

NoSQL Injection in Meteor.js Application

Software Development   -  

August 06, 2016

Table of Contents

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

FYI: This is one of two topics of our 2nd Meteor Meetup on July 9th, 2016. The author is Son Le, a young talent member of Designveloper.

Before digging into every facet of this post, you are required to have a fairly good background in 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

All thing about NoSQL Injection in Meteor Application

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 statements 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 compromise the security of a web application with a 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 an 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 resulting 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. In this way, attackers can get any arbitrary user data, given the username.

Please check out the list of "Meteor for Beginners - Easy and Practical" videos:

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 their 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 stand for “greater than”. The password is not validated to ensure that it is a string. Therefore, when the JSON document is deserialized, that field may contain anything but the string that can be used to manipulate the structure of the query. You can get that what the query does is compare 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 puts Meteor apps at 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 the README.md file for how to set up and run the app on your local machine.

All thing about NoSQL Injection in Meteor Application

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 a developer) are expecting the slug information to be a string, but haven’t checked for that condition. So whatever input can be injected into this function, makes it vulnerable to NoSQL Injection. For example. an attacker can do this (in the 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.

Solutions to the Problems

Through those examples above, hopefully, you can see the potential of NoSQL Injection being a threat to apps using NoSQL databases. So how do we prevent this problem?

Fortunately, it’s pretty easy in the scope of Meteor to prevent the app from being attacked by NoSQL Injection. In general, there’s only one thing to keep in mind: Never completely trust user inputs. We must always get them validated before passing them as parameters to publication functions and methods.

Meteor has a handy package that does the exact same thing called to check. This package will allow us, developers, to check if the input parameter matches the defined type. So, one can’t inject a JavaScript object as a parameter to a function that requires a string, for example.

The check package is quite useful but what if your project has so many publication functions/methods that you don’t know if their parameters have been checked or not? Then here comes audit-argument-check and check-checker, those packages will throw warnings if there’re methods that haven’t been checked by the check package.

Wrapping Up!

Walking through this blog, we’ve discovered more about NoSQL Injection:

  • How it works and some examples
  • How to prevent it in general and in the scope of Meteor
  • So, did you find some great information on your own in this blog? What am I missing? Let me know in the comments and I’ll add it!

If you enjoyed this post, I’d be very grateful if you’d help it spread by emailing it to a friend or sharing it on Twitter or Facebook. Thank you!

Also published on

Share post on

Insights worth keeping.
Get them weekly.

body

Subscribe

Enter your email to receive updates!

name name
Got an idea?
Realize it TODAY
body

Subscribe

Enter your email to receive updates!