|
| 1 | +# NoSQL Security Cheat Sheet |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | +NoSQL databases (MongoDB, CouchDB, Cassandra etc.) power many modern applications with flexible schemas and horizontal scale. But their different query models and deployment patterns create **more security risks** compared with relational databases. |
| 6 | +This cheat sheet summarizes guidance to reduce risk when using NoSQL systems. |
| 7 | + |
| 8 | +## Threats & Common Failure Modes |
| 9 | + |
| 10 | +- **NoSQL Injection** — Unsafe construction of query objects or query strings from untrusted input. |
| 11 | +- **Exposed Management Interfaces** — Admin GUIs, database ports or REST endpoints exposed to the internet. |
| 12 | +- **Weak/No Authentication & Authorization** — Default open access or excessive privileges for clients. |
| 13 | +- **Insecure Network Exposure** — No TLS, open ports, insufficient network segmentation. |
| 14 | +- **Insecure Defaults** — Default admin accounts, default passwords, unsecured configs. |
| 15 | +- **Poor Access Control Models** — Coarse roles allowing lateral abuse. |
| 16 | +- **Insecure Serialization / Deserialization** — Remote code execution via unsafe object deserialization. |
| 17 | +- **Misconfigured CORS / Public APIs** — APIs accidentally allow cross-origin requests or wide access. |
| 18 | +- **Credential & Secret Leaks** — Hardcoded DB credentials in code, images, CI logs. |
| 19 | +- **Unsafe Backup Exposure** — Backups left unencrypted or publicly accessible. |
| 20 | +- **Supply-chain / Dependency Risks** — Vulnerable drivers, ORMs/ODMs, or plugins. |
| 21 | + |
| 22 | +## Secure-by-Design Principles |
| 23 | + |
| 24 | +- **Treat all input as untrusted** — validate, sanitize, and normalize. |
| 25 | +- **Use least privilege** — narrow roles for users, services, and operators. |
| 26 | +- **Defense in depth** — combine network controls, auth, input validation, and monitoring. |
| 27 | +- **Secure defaults** — change default ports/accounts, enable auth and TLS by default. |
| 28 | +- **Automate secrets & rotation** — vaults and short-lived credentials. |
| 29 | +- **Monitor & audit** — log access and detect anomalies. |
| 30 | + |
| 31 | +## Practical Defenses & Examples |
| 32 | + |
| 33 | +### Prevent NoSQL Injection |
| 34 | + |
| 35 | +**Unsafe (string-based filter building — Node.js / MongoDB):** |
| 36 | + |
| 37 | +```js |
| 38 | +// DANGEROUS: building query from untrusted input |
| 39 | +const q = "{ name: '" + req.query.name + "' }"; |
| 40 | +const filter = eval("(" + q + ")"); // NEVER do this |
| 41 | +db.collection('users').find(filter) |
| 42 | +``` |
| 43 | + |
| 44 | +**Safe (use driver query objects / parameterization):** |
| 45 | + |
| 46 | +```js |
| 47 | +// SAFE: let driver handle query structure |
| 48 | +const filter = { name: req.query.name }; |
| 49 | +db.collection('users').find(filter) |
| 50 | +``` |
| 51 | + |
| 52 | +**Safe (whitelisting for operators):** |
| 53 | + |
| 54 | +```js |
| 55 | +// Reject operator injection by disallowing $ in keys or operator values |
| 56 | +if (JSON.stringify(req.body).includes('"$')) throw Error("Invalid input"); |
| 57 | +``` |
| 58 | + |
| 59 | +Notes: |
| 60 | + |
| 61 | +- Do **not** accept raw JSON fragments from the client to execute as queries. |
| 62 | +- Disallow client-controlled query operators (like `$where`, `$regex`, or `$expr`) unless strictly required and validated. |
| 63 | +- For text-based search parameters, use safe driver APIs (e.g., `$text` with controlled input). |
| 64 | + |
| 65 | +### Use Secure Driver / ODM Patterns |
| 66 | + |
| 67 | +- Prefer high-level APIs (ODM/ORM) that build queries safely (e.g., Mongoose, Spring Data, Datastax driver patterns). |
| 68 | +- Avoid `.eval()`-like functionality and raw query execution from untrusted data. |
| 69 | +- Sanitize and validate any raw expressions before passing to the DB. |
| 70 | + |
| 71 | +#### Example — PyMongo safe usage |
| 72 | + |
| 73 | +```python |
| 74 | +from pymongo import MongoClient |
| 75 | +client = MongoClient(uri, tls=True) |
| 76 | +collection = client.mydb.users |
| 77 | +user = collection.find_one({"email": email_input}) |
| 78 | +``` |
| 79 | + |
| 80 | +### Authentication & Authorization |
| 81 | + |
| 82 | +- **Enable authentication** (do not run databases unauthenticated). |
| 83 | +- Use **role-based access control (RBAC)**, least privilege for service accounts. |
| 84 | +- Use **separate users** for admin/backup/readonly/application. |
| 85 | +- Use identity federation or short-lived credentials when supported (e.g., AWS IAM -> DynamoDB). |
| 86 | + |
| 87 | +For more information please check following cheat sheets: |
| 88 | + |
| 89 | +[Authentication Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html) |
| 90 | + |
| 91 | +[Authorization Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Authorization_Cheat_Sheet.html) |
| 92 | + |
| 93 | +### Network & Transport Security |
| 94 | + |
| 95 | +- **Bind services to internal interfaces**, not `0.0.0.0`. |
| 96 | +- Use **network segmentation / private subnets** and security groups. |
| 97 | +- **Enforce TLS** (in transit encryption) for driver connections and admin consoles. |
| 98 | +- Turn off remote management or restrict it to admin networks/VPNs. |
| 99 | + |
| 100 | +### Configuration Hardening |
| 101 | + |
| 102 | +- Change default ports and disable sample/demo users. |
| 103 | +- Turn off or restrict features that execute code on the server (e.g., MongoDB `db.eval`, server-side scripting). |
| 104 | +- Require TLS for internal replication links where supported. |
| 105 | + |
| 106 | +### Secrets Management |
| 107 | + |
| 108 | +- Do **not** hardcode DB credentials — use a secret manager (Vault, AWS Secrets Manager, Azure Key Vault). |
| 109 | +- Avoid baking credentials into container images or environment variables in CI logs. |
| 110 | +- Rotate credentials regularly and use ephemeral tokens when possible. |
| 111 | + |
| 112 | +### Logging, Monitoring & Auditing |
| 113 | + |
| 114 | +- Enable audit logging (connection attempts, admin actions, failed auth). |
| 115 | +- Send logs to a tamper-evident SIEM. |
| 116 | +- Alert on anomalous patterns (spike in queries, slow queries, large data exports). |
| 117 | +- Monitor for suspicious commands (e.g., admin actions, `$where`, map-reduce jobs). |
| 118 | + |
| 119 | +### Backups & Snapshots |
| 120 | + |
| 121 | +- Encrypt backups at rest and during transfer. |
| 122 | +- Restrict access to backup storage. |
| 123 | +- Sanitize backups for PII as required by policy. |
| 124 | +- Validate restore procedures regularly. |
| 125 | + |
| 126 | +## Quick NoSQL Security Checklist |
| 127 | + |
| 128 | +- Enable authentication & RBAC |
| 129 | +- Enforce TLS for client and node communication |
| 130 | +- Bind DB to internal IPs / use private networks |
| 131 | +- Use least privilege service accounts |
| 132 | +- Disallow client-controlled query operators unless validated |
| 133 | +- Avoid raw query execution / eval on server |
| 134 | +- Store credentials in secret manager & rotate them |
| 135 | +- Harden configs (disable unsafe defaults) |
| 136 | +- Encrypt and secure backups |
| 137 | +- Monitor/audit DB access and admin actions |
| 138 | +- Keep DB and drivers patched |
| 139 | + |
| 140 | +## Do’s and Don’ts |
| 141 | + |
| 142 | +**Do**: |
| 143 | + |
| 144 | +- Use driver query objects rather than building query strings. |
| 145 | +- Validate and whitelist user-supplied fields (columns/keys). |
| 146 | +- Restrict management interfaces and require MFA for admin access. |
| 147 | +- Automate security testing in CI/CD pipelines. |
| 148 | + |
| 149 | +**Don’t**: |
| 150 | + |
| 151 | +- Expose DB ports/admin consoles to the public Internet. |
| 152 | +- Accept raw JSON queries from clients or eval untrusted strings. |
| 153 | +- Use root/admin DB accounts for application connections. |
| 154 | +- Rely only on network controls to protect badly written queries. |
| 155 | + |
| 156 | +## Examples of Dangerous Patterns (brief) |
| 157 | + |
| 158 | +- Allowing client to submit `{ "$where": "this.balance > 0" }` → remote code execution or heavy CPU. |
| 159 | +- Concatenating user input into query language strings or shell commands for DB tools. |
| 160 | +- Leaving MongoDB unsecured (no auth) listening on public IP. |
| 161 | + |
| 162 | +## References |
| 163 | + |
| 164 | +- [MongoDB Security Official Document](https://www.mongodb.com/docs/manual/security/) |
| 165 | +- [Security best practices for Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices-security.html) |
| 166 | +- [WSTG - Testing for NoSQL Injection](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection) |
0 commit comments