Databases

Secure MongoDB with cnspec

Scan self-hosted MongoDB servers against security and compliance best practices with cnspec.

Scan the MongoDB servers you run yourself to find security risks before they become incidents. cnspec evaluates authentication and authorization, TLS mode and cluster authentication, server-side JavaScript, audit log configuration, users and their roles, custom roles and the privileges they grant, and server parameters.

cnspec connects with a MongoDB user and inventories the server through read-only administrative commands (buildInfo, getCmdLineOpts, getParameter, usersInfo, rolesInfo, listDatabases). It never touches your data.

This is the provider for MongoDB servers you operate. For the managed service, see Secure MongoDB Atlas with cnspec.

If you're new to cnspec, start with the Quickstart. For an overview of every database cnspec can scan, see the database scanning overview.

Prerequisites

To scan MongoDB with cnspec, you must have:

  • cnspec installed on your workstation
  • Network access to the server on its port (27017 by default)
  • A user with the built-in clusterMonitor role and read access to the admin database

Authenticate

cnspec authenticates with a MongoDB user and password over SCRAM:

cnspec shell mongo db.contoso.com --user admin --ask-pass

For a verified-TLS connection, add the CA flag:

cnspec shell mongo db.contoso.com --user auditor --ask-pass --tls --tls-ca ca.pem

Prefer a least-privileged account for auditing. clusterMonitor plus read on admin covers everything below. Without those privileges the users, roles, and parameters collections return empty rather than failing the scan, so confirm mongo.instance.users is populated before trusting a passing account check.

Connection options

OptionDescription
--hostServer hostname or IP address (also accepted as the positional argument)
--portServer port (default 27017)
--userUser to authenticate as
--passwordPassword, or --ask-pass to be prompted
--auth-dbAuthentication database (default admin)
--tlsConnect over TLS
--tls-caPath to a CA certificate to verify the server
--tls-insecureSkip server-certificate verification (testing only)
--discoverauto (default), all, databases, instance, or none

Verify with a quick MongoDB check

cnspec shell mongo db.contoso.com --user admin --ask-pass
cnspec> mongo.instance { version authorizationEnabled tlsMode javascriptEnabled }
mongo.instance: {
  version: "7.0.39"
  authorizationEnabled: true
  tlsMode: "disabled"
  javascriptEnabled: true
}

If cnspec connects and shows the version, you're ready to scan.

Scan MongoDB

By default cnspec discovers each database as its own mongo-database asset alongside the server asset:

cnspec scan mongo db.contoso.com --user auditor --ask-pass

To scan the server only:

cnspec scan mongo db.contoso.com --user auditor --ask-pass --discover none

When a scan completes, cnspec prints a summary of all the checks it ran, grouped by policy, along with a risk score from 0 (no risk) to 100 (highest risk). Failed checks include remediation guidance to help you fix issues. To learn more about reading scan results, read Understand cnspec Results.

Mondoo doesn't yet ship an out-of-the-box policy for self-hosted MongoDB. The resources are shaped around the CIS MongoDB Benchmark, so the checks below map closely to its recommendations. Use them as a starting point and create your own policies to meet your requirements.

Explore and test checks interactively

cnspec shell mongo db.contoso.com --user auditor --ask-pass

List users

cnspec> mongo.instance.users { user db isPrivileged mechanisms }

List custom roles

cnspec> mongo.instance.roles.where(isBuiltin == false) { role db }

Inspect the privileges a role grants

cnspec> mongo.instance.roles.where(role == "appReadMetrics").first.privileges { database collection actions }
mongo.instance.roles.where.first.privileges: [
  0: {
    database: "appdb"
    collection: "metrics"
    actions: ["find"]
  }
]

Read a server parameter

cnspec> mongo.instance.parameters.where(name == "authenticationMechanisms") { name value }

List databases

cnspec> mongo.instance.databases { name sizeOnDisk empty }

Example security checks

Ensure authentication is enabled

Without it, anyone who reaches the port is a full administrator:

cnspec> mongo.instance.authenticationEnabled == true
[ok] value: true

Ensure role-based access control is enforced

cnspec> mongo.instance.authorizationEnabled == true
[ok] value: true

Ensure TLS is required

allowTLS and preferTLS both still accept plaintext connections:

cnspec> mongo.instance.tlsMode == "requireTLS"
[ok] value: true

Ensure server-side JavaScript is disabled

Server-side JavaScript widens what a query injection can reach:

cnspec> mongo.instance.javascriptEnabled == false
[ok] value: true

Ensure the server is not bound to every interface

cnspec> mongo.instance.bindIp != "0.0.0.0"
[ok] value: true

Ensure cluster members authenticate with x.509

A shared key file authenticates every member with the same secret, so one compromised node yields the cluster:

cnspec> mongo.instance.clusterAuthMode == "x509"
[ok] value: true

Ensure auditing is configured

cnspec> mongo.instance.auditLogDestination != ""
[ok] value: true

Ensure logs are appended rather than overwritten

Without logAppend, a restart discards the previous log, and with it the record of what happened before the restart:

cnspec> mongo.instance.logAppend == true
[ok] value: true

Ensure only SCRAM-SHA-256 is offered

cnspec> mongo.instance.users.all(mechanisms.none(_ == "SCRAM-SHA-1"))
[ok] value: true

Review privileged accounts

cnspec> mongo.instance.users.where(isPrivileged) { user db roles { role db } }

Review roles that grant cluster-wide privileges

A privilege with cluster set applies to the whole deployment rather than one database:

cnspec> mongo.instance.roles.where(isBuiltin == false) { role db privileges.where(cluster) { actions } }

Review roles that reach every collection in a database

An empty collection means the privilege covers all of them:

cnspec> mongo.instance.roles.where(isBuiltin == false) { role privileges.where(collection == "" && cluster == false) { database actions } }

Learn more

To assess a mongod.conf file on disk rather than a running server, the os provider exposes a mongodb resource that parses it directly.

On this page