Top 10 security best practices for MongoDB

The world is becoming increasingly aware of the massive amounts of data floating around the internet. Not surprisingly, many people have concerns about this. These concerns have led to a lot of legislation around data privacy, of which GDPR is just one of many. On top of all of this, there’s been the exposure of thousands of MongoDB databases on the internet. While many of these databases were left open to the world unintentionally, the result was still the same—the loss of customer data and trust.

While the peak of the MongoDB Apocalypse may have passed, MongoDB databases are still being exploited today, and it’s always smart to take proactive steps on hardening your MongoDB security. Security needs to start at the beginning. In order to assist you in strengthening your database security, we’ve put together the following ten security best practices for MongoDB. By following the below best practices, you’ll be starting off on the right foot and walking in the right direction. Read on to learn how to keep your database secure and your data safe.

Enable access control

MongoDB doesn’t enable access control by default. Running a MongoDB instance without access control means that anyone that can connect to the database can run commands and potentially see all data in the database. As you can imagine, this has led to the exposure of massive amounts of data in breaches over the years. Before enabling access control, you have to create an administrative user with specific permissions. Once done, enable the authentication option in the configuration and restart the MongoDB service. Now any users connecting to the database will need to authenticate with the proper credentials. The MongoDB documentation has a great walk-through on the specifics of creating the administrative user and enabling the access control option.

Configure role-based access control

After enabling access control to force all users to authenticate when connecting to the database, the next step is to configure role-based access control (RBAC). The RBAC model uses a system of privileges and roles that govern what a user can do. These privileges can restrict users to only reading or updating specific collections. The RBAC model provides a system of fine-grain control that, when done well, can go a long way towards protecting the contents of the database in the event of a user compromise.

Encrypt network traffic

Data doesn’t just magically appear in a database. It has to get there somehow, and that’s usually through a network connection. Out of the box, all of this network traffic is in the clear. This means that anyone with the ability to perform a person-in-the-middle attack can see this data. While the attacker needs to have the right network visibility to perform their attack, the risk is still present. Configuring Transport Layer Security (TLS) will encrypt all traffic to and from the database. This is incredibly important and no database should be in use without network encryption. Even if all the connections are behind firewalls and there’s no external exposure, those internal connections still need to use TLS to reduce the risk that a breach of an environment will lead to additional database breaches.

Use at rest encryption

Encrypting data at rest is an option only available in the Enterprise edition of MongoDB. If you’re using that version, it’s straightforward to enable at rest encryption. At rest encryption will protect the contents of the database in the event that someone is able to copy the database files (in a backup for instance) or the server image, or even steal the physical server. It doesn’t help protect data that an application is accessing during normal operations, but it’s still a crucial part to securing a MongoDB instance properly.

Restrict network exposure

Now is a great time to also review the security of the network topology that hosts the MongoDB database. This is a huge topic covering a lot of network hardening. However, there’s one specific MongoDB option that warrants special attention. That is to ensure the instance is only listening on the localhost interface. In older versions of MongoDB, this wasn’t the case, which resulted in exposure to outside connections. This, along with not enabling access control, has been responsible for the majority of MongoDB data leaks. Luckily, in recent versions, this is no longer the case; however, you should check for this configuration in existing databases and update accordingly.

Configure system auditing

Another Enterprise-only option, the built-in system auditing tracks all changes to the data and database configurations. After configuring system auditing, audit events can be written to a syslog connection or written to a file. These events can then be sent to a more robust log aggregator or, better yet, a security information and event management (SIEM) tool. A SIEM provides real-time analysis of security events throughout the network to identify malicious activity. MongoDB audit events are a great addition to this dataset to enable correlation with other potentially malicious activity.

Use the official MongoDB packages

Installing MongoDB is pretty straightforward since all the popular Linux distributions have the MongoDB packages in their respective repositories. One caveat, however, is to ensure that the packages are official MongoDB packages and pass the authenticity checks. You also need to ensure that the package maintainers for whatever system you’re using are staying up to date with MongoDB releases so that you don’t miss important security updates. In order to avoid these issues, it’s preferable to use the official MongoDB package repositories and not one specific to your operating system distribution.

Stay up to date with MongoDB security fixes

Attackers are always looking for new exploits, and nothing stays secure for very long. Because of this, it’s incredibly important to stay on top of the security updates and bug fixes that the MongoDB maintainers release. This is so important that MongoDB has an alerts page specifically for this purpose. If you’re using the official package repositories as the previous tip pointed out, you’ll get these releases as soon as they’re available. The last thing you want to happen is to fall so far behind in tracking updates that it becomes a huge project to update to the most recent stable version. Having a process in place to update and keep MongoDB current is a great way to ensure that you’re staying on top of patches and to reduce technical debt.

Disable JavaScript execution

Certain MongoDB operations allow you to execute arbitrary JavaScript expressions. I don’t know about you, but whenever I hear the words “arbitrary” and “execute” in the same sentence in a security context, I immediately pay attention. These troublesome operators—$where, mapReduce, and group—can be incredibly dangerous. For example, the following query is susceptible to NoSQL injection:

var query = { 
$where: "this.userName === '" + req.body.userName + "'" 
}

The query uses the $where operator to retrieve a list of users with a specific user name. The req.body.userName comes directly from the request data, which is user controlled. This means that an attacker could use the following value as a user name:

'\'; return \'\' == \''

This has the effect of changing the query to the following expression:

this.userName === ''; return '' == ''

This results in an always true expression that results in returning all the users in the database and not the specific one intended.

Luckily, in most cases, you don’t need JavaScript expressions and can use MongoDB operators to do what you need to. In this case, it’s a great idea to disable JavaScript execution entirely. The maintainers of the open-source mongoaudit tool have a great write-up on how to disable JavaScript execution.

Know your frameworks

Finally, one of the things that I’ve seen over the years throughout many security assessments is when developers mistakenly assume what a framework is doing (or not doing). It’s a very common practice to interface with MongoDB from a framework that abstracts out some of the underlying complexity while providing convenient modeling capabilities. When using a framework (which you should), it’s very important to understand how it’s handling queries and the framework’s sanitization and validation capabilities. Like SQL injection attacks for relational databases, MongoDB is also susceptible to NoSQL injections. If an attacker is able to influence the queries being run, this is a very real threat. Frameworks do a great job of protecting against these issues, but they aren’t perfect and there’s only so much they can do. If maintaining data validation practices in frameworks is too much manual work, there are tools available for protecting MongoDB databases against NoSQL injections and other attacks as well. 

Conclusion

There’s far more to securing a server or a database than a single blog post can cover. However, following the above ten best practices will immensely increase the security of your MongoDB databases. These suggestions coupled with good server hardening practices will keep you out of the news. And, most importantly, your data is protected and safe where it belongs. Be sure to also check out the MongoDB security page and their security checklist. These have additional actions you can take to even further increase the security of your databases.


This post was written by Casey Dunham. Casey, who recently launched his own security business, is known for his unique approaches to all areas of application security, stemming from his 10+ year career as a professional software developer. His strengths include secure SDLC development consulting; threat modeling; developer training; and auditing web, mobile, and desktop applications for security flaws.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments