Table of Contents
    Get answers from the Community
    Join discussions

    MEAN stack applications (MongoDB, Express.js, AngularJS, and Node.js) are becoming increasingly popular as lightweight, easily deployable frameworks due to a vast ecosystem of middleware plugins and dependencies. But just how secure are these technologies?

    Let’s examine some common vulnerabilities that are introduced either by using these components in their default configurations or due to common developer mistakes. Throughout this series, we will demonstrate each of these issues using an intentionally vulnerable MEAN Bug application, as well as provide mitigating techniques that developers can use to protect their applications from these issues. These articles focus on the security-related issues and assume that the reader has a basic understanding of the MEAN stack technologies.

    Query selector injection (MongoDB)

    The first piece of the technology stack that we will examine is the MongoDB database. This NoSQL database is immune to conventional SQL injection attacks, but is vulnerable to a similar attack called Query Selector Injection or NoSQL Injection which uses built-in logic operators to alter queries. To demonstrate, let’s look at the login form for our example application.

    MEAN11new

    Figure 1: MEAN Bug login form

    Using Burp Suite web proxy we have intercepted the login request and changed the POST pass parameter to pass[$ne]= where $ne is the MongoDB query operator ‘not equal to’.

    mean21new

    Figure 2: Form parameter modified with HTTP proxy tool Burp Suite

    When Express processes the x-www-form-urlencoded request body, this will be parsed into the object {user: ‘admin’, pass: {$ne: null} and passed to the MongoDB query in the code block below.

    mean31

    With the above payload, the query will match the first username that matches ‘admin’ with a password that is not equal to null, allowing us to authenticate to the application as an administrator without providing a valid password.

    mean41new

    Figure 3: Bypassed authentication and accessed the application welcome page

    If we attempt the same injection attack on the /secure/query API, we see that the request contains a JSON body which, unlike a simple POST body, is not vulnerable to attribute pollution when parsed by Express.

    mean51new

    Figure 4: Initial request contains JSON body

    However, if we change the Content-Type header to x-www-form-urlencoded and modify the body to contain our payload we can continue to use the Express parser to insert a query selector into the request object. This allows us to execute another Query Selector Injection attack and obtain all the invoices in the database.

    mean61new

    Figure 5: Content-Type header and request body are modified to exploit Express parser

    Perhaps the simplest way to mitigate query selector injection is to cast the values to a String before running the query. The vulnerable authentication query from the first example has been modified with the code block below.

    mean71

    If we re-submit the malicious request, the password will be matched against the String ‘$ne: null’ rather than evaluating the actual query operator ‘not equal to’. As a result, the authentication bypass attack no longer works.

    mean81new

    Figure 6: Query selector injection attack failed after casting input to String

    Alternatively, an input validation tool such as mongo-sanitize can be used to reject any request key beginning with the $ character used to denote query operators.


    Insecure configuration (MongoDB)

    By default, MongoDB does not enforce authentication, meaning anyone can connect to and directly query the database. To further complicate this issue, MongoDB versions prior to 2.6.0 are bound to all interfaces by default. Whether the result of using an older instance with default configurations or explicitly binding a newer instance to a public interface, MongoDB databases are often exposed to the open internet. As demonstrated with our example application, we can connect directly to the MongoDB users database from an external system without any authentication using the Mongo Shell utility.

    mean91

    Figure 7: Accessing MongoDB users database directly with Mongo Shell

    MongoDB also provides an optional HTTP and REST interface which, if enabled, exposes sensitive information about the databases and the underlying file system. These interfaces may be enabled in the configuration file as shown below or from the command line when starting the MongoDB instance. By default, they will bind to the database port plus 1000 (i.e., 28017).

    mean101
    mean111new

    Figure 8: HTTP interface exposes system and database information

    mean121new

    Figure 9: Enabling the REST interface allows us to run commands such as ‘listDatabases’

    To secure the MongoDB instance, the /etc/mongodb.conf file’s bind_ip, auth, httpinterface, and rest options should be configured to restrict access appropriately as demonstrated in the excerpt below.

    mean131

    As of January 2017, more than 40,000 MongoDB instances have been compromised by ransomware that exploits these servers’ insecure default configuration. You should take a few moments to ensure that your MongoDB instance is properly hardened so that it does not become a statistic.