MongoDB Insecurity Levels and How to Avoid Them

Onyancha Brian Henry

Most database management systems have several techniques of securing their data from an outsider or an unauthorized person or application. The techniques prevent your data from being read or copied without the user’s permission.

MongoDB is not any different as it has some insecurity levels. In this blog post, we will discuss the insecurity levels in MongoDB and how to avoid them so that you can protect your MongoDB installation.

For the safety and security of your MongoDB, the following are some of the major security measures to consider strictly:
 

  1. Authentication of user connections.

  2. Authorization/ Role-Based access control.

  3. Network Encryption/ Transport Encryption.

  4. Storage Encryption/ Encryption-at-rest.

  5. Auditing.

In this article, we will be looking at the above security measures in detail, with much focus on Authentication and Authorization.

Authentication and Authorization

Authentication and Authorization must be activated in unison. However, they can be used independently of each other. Authentication prevents access to an unknown person who has network access to the database server from copying or damaging the database data. Authentication requires all clients and servers to provide valid credentials before they can connect to the system.  Authorization on the other hand, prevents an application or a user from reading, altering or deleting data other than what they were supposed to. 

To configure Role-Based access control;

  1. Create a user administrator first.

  2. Create additional users.

  3. Then create a unique MongoDB user for each person/application that accesses the system.

  4. By following the principle of least privilege, you should create roles that define the exact access rights needed by a set of users.

  5. Then assign the users only the roles they need to perform in their operations. A user can be a client application or a person.

You should note that a user can have privileges across different or multiple databases. In that scenario, instead of creating a user multiple times in different databases, create a single user with roles that grant applicable database privileges.

More often than not, these two security measures might be confused to mean the same thing. In some scenarios, they are similar to each other, but they are also different.

Similarities between Authentication and Authorization

  • Both are somewhat of a single unit because, when you enable Authentication, Authorization is enabled automatically. Authorisation is enabled in unison with Authentication hence connections from unknown users will have no privilege to access database data. Authorization also requires the user name to be verified by Authentication so as to know which privileges apply to a connection’s requests. Therefore, it cannot be enabled independently to the other either.

  • They are also both similar in unfortunate, legacy naming of configuration options. The configuration file option for authentication is security.authorization instead of security authentication as it would be expected. When you use the command though, Authentication is the first to be enabled and Authorization is only enabled as an after-effect. “-auth” is the command line argument for enabling authentication which automatically forces authorization to be on too.

Differences between Authentication and Authorization

  • These two are different because they are two parts of the software that have different functions.

Authentication == User identity, by means of credential checking.

Authorization == Assigning and enforcing DB object and DB command permissions.

  • During initial setup, Authentication is disabled for localhost connections. This is brief though as you get one opportunity to create the first user, then the exception ( to the Authentication and Authorization on together rule) privilege is dropped.

How to Check if Authentication and Authorization are Enabled or Not

The first versions of MongoDB had “- auth” set off by default and this is widely regarded as a bad move. Even in version 4.0 it was still off by default. Blank configuration still equates to authorization being off despite having startup warnings and various exposure reductions  such as localhost becoming the only default-bound network device in MongoDB v3.6.

You are not using Authentication or rather you don’t have Authentication enabled if the mongod configuration files do not:

  1. Have security.authorization set to ‘enabled.’

  2. Include a security.keyfile.

  3. Include a security.clusterAuthMode setting which forces authentication to be on.

To double-check if you have authentication and Authorization enabled or not, you can try this quick mongo shell one-liner (with no user credential arguments set):

mongo --host <target_host>:<port> --quiet --eval 'db.adminCommand({listDatabases: 1})'

The response you should get is an “unauthorized” error. But, on the other hand, if you get a list of database names, then automatically that means you have a naked MongoDB deployment.

External Authentication

As the name suggests, external authentication is about allowing users to be authenticated in an external service. As an exception, it can not be used for the internal mongodb __ system user, but using it for any real human user or client application service account is perfectly suitable.

Simply, the external auth service will be a Kerberos KDC, or an ActiveDirectory or OpenLDAP server. You should note that using external authentication does not prevent you from having ordinary MongoDB user accounts at the same time.

Internal Authentication

On the contrary, MongoDB internal authentication does not mean the opposite of external authentication. This is because a mongod node running with authentication enabled will not trust that any TCP peer is another is another mongod or mongos node just because it communicates like one. Rather, it requires that the peer authenticates by proof of shared secret.

There are two types of internal authentication mechanisms in MongoDB:

  1. Keyfile internal authentication.

  2. SCRAM or x.509 internal authentication.

Keyfile Internal Authentication

This is the default internal authentication mechanism in MongoDB. The term “Key” indicates an asymmetric encryption key but in real sense it is just a password no matter how you generated it. The keyfile is saved in an identical file distributed to each mongod and mongos node in the cluster. In the scenario the password is used successfully, a mongod node will permit commands coming from the authenticated peer to run as the “_ _ system” superuser.

If someone has a copy of the keyfile, they can simply strip control and non-printing chars from the keyfile to make the password string that will allow them to connect as the “_ _ system” user.

However, if that happens and you run the command below as the mongod (or root) user on one of your MongoDB servers and succeed, you should not worry as there will be no accidental read-privilege leaking. This is because the mongod will abort on startup if the keyfile is in anything other than 400 (or 600) file permissions mode.

mongo --authenticationDatabase local -u __system -p "$(tr -d '\011-\015\040' < /path/to/keyfile)"

However, accidentally saving the keyfile in your world-readable source control may allow users who are not DBAs (or the server admins with root) to read a copy of the keyfile. This is considered as a security failure.

An extreme risk increases when the keyfile is distributed with mongos nodes owned and run as one of the application team’s unix users instead of “mongod” or other DBA team-owned unix user.

SCRAM or x.509 Internal Authentication

The x.509 internal authentication mechanism actually uses asymmetric private or public keys and must be used in union with TLS/SSL. This mechanism can be used for  client connections as well as internal authentication.

The x.509 or SCRAM mechanism has an advantage over the Keyfile mechanism because in the x.509 mechanism, it is less likely that one of the keys deployed with mongod and mongos nodes can be abused by an intruder who gets a copy of it. However, this depends on how strictly the x.509 certificates are set up. To enjoy maximum security from this mechanism, you should have a dedicated security team that understands the x.509 concepts and best practices. These best practices include tightening down which hosts it will work on, and being able to revoke and rollover certificates. 

Network Encryption/ Transport Encryption

Network encryption prevents someone from copying the data that is being transferred over a network link somewhere between two servers. Network encryption requires little or no thought when it comes to deciding whether to use it as it is crucial. But if, for example, your MongoDB cluster and all its clients are inside a virtual private network that you believe has no holes in its firewall and no privilege escalation risk from other apps, then you do not need network encryption.

For network encryption, you should configure MongoDB to use TLS/SSL for all outgoing and incoming connections. Encrypt communication between mongod and mongos components of a MOngoDB deployment as well as between all applications and MongoDB using TLS/SSL.

Starting in version 4.0; MongoDB disables support for TLS 1.0 encryption on systems where TLS 1.1+ is available and it also uses the following native TLS/SSL libraries:

  1. Windows - Secure Channel (Schannel).

  2. Linux/BSD - OpenSSL.

  3. macOS - Secure Transport.

Limit Network Exposure

You should ensure that MongoDB runs in a trusted network environment and also configure firewall or security groups to control inbound and outbound traffic for your MongoDB instances. More so, configure to only allow trusted clients to access the network interfaces and ports on which MongoDB instances are available. For example, use IP whitelisting to allow access from trusted IP addresses.

Run MongoDB withSecure Configuration Options

MongoDB supports the execution JavaScript code for the following server-side operations:

  1. mapReduce.

  2. $where.

  3. $accumulator.

  4. $function.

Use the -- noscripting option on the command line to disable server-side scripting if you do not use the above operations. Keep input validation enabled although MongoDB enables input validation by default through the net.wireObjectCheck setting. This ensures that all documents stored by the mongod intsance are valid BSON.

MongoDB Storage Encryption/ Encryption-at-rest

Storage encryption prevents someone from obtaining a copy of the underlying database files. This might happen when someone breaks into your datacenter and steals your server’s hard disk. MongoDB data includes data files, configuration files, auditing logs, and key files.

Starting with MongoDB Enterprise 3.2, you can encrypt data in the storage layer with the WiredTiger storage engine’s native Encryption-at-rest. MongoDB data should be encrypted on each host using file-system, device, or physical encryption when not using WiredTiger’s encryption-at-rest. Also, you should collect logs to a central log store as these logs contain DB authentication attempts including source IP address. However, storage encryption has a slight performance cost.

Auditing

Auditing helps in tracking a database user who knows how to cover up their tracks after changing or altering database data. Basically, auditing tracks access and alterations to database configurations and data. MongoDB Enterprise has  an auditing system facility that can record system events such as user operations and connection events on a MongoDB instance. 

These audit records help in forensic analysis and allow administrators to verify proper controls. Auditing is of high value to some users but can only be so, when certain other risks are eliminated. For example, an attacker cannot gain Unix root access on the servers while running the live mongod nodes.

Moving Forward

You can set up filters to record specific events like authentication events. But be careful because when the audit filters are made too broad, its performance will quickly choke leading to high performance costs. Although, if auditing is used appropriately, there won’t be much performance costs.

ClusterControl
The only management system you’ll ever need to take control of your open source database infrastructure.