Skip to main content

Documentation Index

Fetch the complete documentation index at: https://guide.codepure.com/llms.txt

Use this file to discover all available pages before exploring further.

Common Misconfiguration

Exposed NoSQL database credentials can lead to data breaches, ransomware attacks, and complete database compromise.

Vulnerable Example

// VULNERABLE - Hardcoded MongoDB credentials
const mongoose = require('mongoose');
const redis = require('redis');
const { Client } = require('@elastic/elasticsearch');

// MongoDB with credentials in URI
const MONGO_URI = 'mongodb://admin:MySecretPass123!@mongodb.production.com:27017/myapp?authSource=admin';

// MongoDB with separate credentials
const mongoConfig = {
    host: 'cluster0.mongodb.net',
    username: 'dbAdmin',
    password: 'MongoDB@Pass2024!',
    database: 'production',
    authSource: 'admin'
};

// Redis with password
const redisClient = redis.createClient({
    host: 'redis.production.com',
    port: 6379,
    password: 'RedisPass123!@#',
    db: 0
});

// Elasticsearch with API key
const elasticClient = new Client({
    node: 'https://elastic.production.com:9200',
    auth: {
        username: 'elastic',
        password: 'ElasticSearch2024!',
        apiKey: 'VnVhQ2ZHY0JDZGJrUW0tZTVhT3g6dWkybHAyYXhUTm1zeWFrdzl0dk5udw=='
    }
});

// Cassandra credentials
const cassandraAuth = {
    username: 'cassandra',
    password: 'cassandra123',
    keyspace: 'production_ks'
};

mongoose.connect(MONGO_URI);

Secure Example

// SECURE - Using environment variables and connection management
const mongoose = require('mongoose');
const redis = require('redis');
const { Client } = require('@elastic/elasticsearch');
const { MongoClient } = require('mongodb');

class SecureNoSQLConnections {
    constructor() {
        this.connections = {};
    }
    
    async connectMongoDB() {
        // Build connection string from environment
        const config = {
            username: process.env.MONGODB_USERNAME,
            password: process.env.MONGODB_PASSWORD,
            host: process.env.MONGODB_HOST,
            port: process.env.MONGODB_PORT || 27017,
            database: process.env.MONGODB_DATABASE,
            authSource: process.env.MONGODB_AUTH_SOURCE || 'admin'
        };
        
        // Validate required fields
        if (!config.username || !config.password || !config.host) {
            throw new Error('MongoDB configuration incomplete');
        }
        
        // Build URI with proper encoding
        const uri = this.buildMongoUri(config);
        
        // Connection options for production
        const options = {
            useNewUrlParser: true,
            useUnifiedTopology: true,
            serverSelectionTimeoutMS: 5000,
            socketTimeoutMS: 45000,
            maxPoolSize: 10,
            minPoolSize: 2,
            ssl: process.env.NODE_ENV === 'production',
            sslValidate: true,
            sslCA: process.env.MONGODB_CA_CERT,
            authMechanism: 'SCRAM-SHA-256',
            retryWrites: true,
            w: 'majority'
        };
        
        try {
            const client = new MongoClient(uri, options);
            await client.connect();
            
            // Verify connection
            await client.db().admin().ping();
            
            this.connections.mongodb = client;
            console.log('MongoDB connected securely');
            
            return client;
        } catch (error) {
            console.error('MongoDB connection failed:', error.message);
            throw error;
        }
    }
    
    buildMongoUri(config) {
        const credentials = encodeURIComponent(config.username) + ':' + 
                          encodeURIComponent(config.password);
        
        // Support replica sets
        const hosts = config.host.includes(',') 
            ? config.host 
            : `${config.host}:${config.port}`;
        
        let uri = `mongodb://${credentials}@${hosts}/${config.database}`;
        
        // Add query parameters
        const params = [];
        if (config.authSource) params.push(`authSource=${config.authSource}`);
        if (process.env.MONGODB_REPLICA_SET) {
            params.push(`replicaSet=${process.env.MONGODB_REPLICA_SET}`);
        }
        
        if (params.length > 0) {
            uri += '?' + params.join('&');
        }
        
        return uri;
    }
    
    async connectRedis() {
        const redisOptions = {
            socket: {
                host: process.env.REDIS_HOST,
                port: parseInt(process.env.REDIS_PORT) || 6379,
                tls: process.env.NODE_ENV === 'production',
                rejectUnauthorized: true
            },
            password: process.env.REDIS_PASSWORD,
            database: parseInt(process.env.REDIS_DB) || 0,
            lazyConnect: true,
            reconnectStrategy: (retries) => {
                if (retries > 10) {
                    return new Error('Redis reconnection attempts exhausted');
                }
                return Math.min(retries * 100, 3000);
            }
        };
        
        // Use Redis Sentinel for HA
        if (process.env.REDIS_SENTINELS) {
            redisOptions.sentinels = JSON.parse(process.env.REDIS_SENTINELS);
            redisOptions.name = process.env.REDIS_MASTER_NAME;
        }
        
        const client = redis.createClient(redisOptions);
        
        // Error handling
        client.on('error', (err) => {
            console.error('Redis error:', err);
        });
        
        await client.connect();
        
        // Test connection
        await client.ping();
        
        this.connections.redis = client;
        console.log('Redis connected securely');
        
        return client;
    }
    
    async connectElasticsearch() {
        // Use Cloud ID for Elastic Cloud
        const config = process.env.ELASTIC_CLOUD_ID ? {
            cloud: {
                id: process.env.ELASTIC_CLOUD_ID
            },
            auth: {
                apiKey: process.env.ELASTIC_API_KEY
            }
        } : {
            node: process.env.ELASTICSEARCH_URL,
            auth: {
                username: process.env.ELASTIC_USERNAME,
                password: process.env.ELASTIC_PASSWORD
            },
            ssl: {
                rejectUnauthorized: true,
                ca: process.env.ELASTIC_CA_CERT
            }
        };
        
        const client = new Client(config);
        
        // Test connection
        const info = await client.info();
        console.log('Elasticsearch connected:', info.body.cluster_name);
        
        this.connections.elasticsearch = client;
        return client;
    }
    
    async closeAll() {
        for (const [name, connection] of Object.entries(this.connections)) {
            try {
                if (connection.close) {
                    await connection.close();
                } else if (connection.quit) {
                    await connection.quit();
                }
                console.log(`${name} connection closed`);
            } catch (error) {
                console.error(`Error closing ${name}:`, error);
            }
        }
    }
}

// Kubernetes Secret example
const k8sSecret = `
apiVersion: v1
kind: Secret
metadata:
  name: nosql-credentials
type: Opaque
stringData:
  mongodb-uri: mongodb://user:pass@mongo:27017/db
  redis-password: your-redis-password
  elastic-api-key: your-elastic-api-key
`;

Detection Patterns

  • MongoDB URI: mongodb(\+srv)?://[^:]+:[^@]+@
  • Redis URL: redis://[^:]*:[^@]+@
  • Elasticsearch: https?://[^:]+:[^@]+@.*:9200
  • CouchDB: https?://[^:]+:[^@]+@.*:5984

Prevention Best Practices

  1. Use Secrets Management: Never hardcode credentials. Load them from environment variables or a secrets manager (like HashiCorp Vault, AWS Secrets Manager, etc.) at runtime.
  2. Implement Connection Pooling: Use a connection pool to efficiently manage and reuse database connections, reducing the overhead of repeated authentication.
  3. Use SSL/TLS: Encrypt all data in transit between your application and the database to prevent sniffing.
  4. Enforce Strong Authentication: Don’t run with authentication disabled. Use modern, strong mechanisms like SCRAM-SHA-256 for MongoDB.
  5. Implement IP Whitelisting: Configure your database (or its firewall/security group) to only accept connections from your application’s specific IP addresses.
  6. Use Least Privilege: Create dedicated database users for your application that only have the permissions they need (e.g., readWrite, not dbAdmin).
  7. Monitor Access: Log and alert on failed login attempts and connections from unexpected sources.
  8. Implement High Availability: Use features like replica sets (MongoDB) or Sentinel (Redis) to ensure your database is resilient to failure.
  9. Audit and Rotate Credentials: Regularly audit who has access and automatically rotate all passwords and API keys.