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
clusterMonitorrole and read access to theadmindatabase
Authenticate
cnspec authenticates with a MongoDB user and password over SCRAM:
cnspec shell mongo db.contoso.com --user admin --ask-passFor a verified-TLS connection, add the CA flag:
cnspec shell mongo db.contoso.com --user auditor --ask-pass --tls --tls-ca ca.pemPrefer 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
| Option | Description |
|---|---|
--host | Server hostname or IP address, or a full mongodb:// or mongodb+srv:// connection string (also accepted as the positional argument) |
--port | Server port (default 27017) |
--user, -u | User to authenticate as |
--password, -p | Password, or --ask-pass to be prompted |
--auth-db | Authentication database (default admin) |
--tls | Connect over TLS |
--tls-ca | Path to a CA certificate to verify the server |
--tls-insecure | Skip server-certificate verification (testing only) |
--discover | auto (default, the server only), all (the server plus one asset per database), databases, instance, or none |
Running MongoDB on a host cnspec already scans? Add a mongo connection to that host's inventory
file alongside its local
connection, and one cnspec scan covers both the operating system and the database. An inventory
file also lets you scan multiple MongoDB servers at once with shared credentials.
Verify with a quick MongoDB check
cnspec shell mongo db.contoso.com --user admin --ask-passcnspec> asset.version
asset.version: "7.0.39"
cnspec> mongo.instance { authorizationEnabled tlsMode javascriptEnabled }
mongo.instance: {
authorizationEnabled: true
tlsMode: "disabled"
javascriptEnabled: true
}If cnspec connects and shows the version, you're ready to scan.
Scan MongoDB
By default cnspec scans the server as a single asset:
cnspec scan mongo db.contoso.com --user auditor --ask-passTo also scan each database as its own mongo-database asset alongside the server, add --discover all:
cnspec scan mongo db.contoso.com --user auditor --ask-pass --discover allWhen 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.
Scan with the Mondoo MongoDB Security policy
Mondoo maintains an out-of-the-box Mondoo MongoDB Security policy that checks authentication, role-based access control, required TLS, and server-side JavaScript. Mondoo Platform also includes the CIS MongoDB 8 Benchmark policy, which evaluates both the running server and, when you scan the host as well, its mongod.conf.
Mondoo Platform users: Enable the policies in your space. In the Mondoo App, go to Findings > Policies, search for "MongoDB", and add the policies. To learn more, read Manage policies in Mondoo Platform.
Open source users: Pass the policy bundle URL directly to cnspec:
cnspec scan mongo db.contoso.com --user auditor --ask-pass \
--policy-bundle https://raw.githubusercontent.com/mondoohq/cnspec/refs/heads/main/content/mondoo-mongodb-security.mql.yamlThe 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-passList 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: trueEnsure role-based access control is enforced
cnspec> mongo.instance.authorizationEnabled == true
[ok] value: trueEnsure TLS is required
allowTLS and preferTLS both still accept plaintext connections:
cnspec> mongo.instance.tlsMode == "requireTLS"
[ok] value: trueEnsure server-side JavaScript is disabled
Server-side JavaScript widens what a query injection can reach:
cnspec> mongo.instance.javascriptEnabled == false
[ok] value: trueEnsure the server is not bound to every interface
cnspec> mongo.instance.bindIp != "0.0.0.0"
[ok] value: trueEnsure 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: trueEnsure auditing is configured
cnspec> mongo.instance.auditLogDestination != ""
[ok] value: trueEnsure 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: trueEnsure only SCRAM-SHA-256 is offered
cnspec> mongo.instance.users.all(mechanisms.none(_ == "SCRAM-SHA-1"))
[ok] value: trueReview 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
- Remote Scanning with Inventory Files: scan multiple MongoDB servers at once with a single inventory file instead of one at a time
- MongoDB Resource Pack Reference: every MongoDB resource and field cnspec can query
- Secure MongoDB Atlas with cnspec: for the managed service's control plane
- Write Effective MQL: guide to authoring checks and queries
To assess a mongod.conf file on disk rather than a running server, the os provider exposes a mongodb resource that parses it directly.