HIGH insufficient loggingsailsmongodb

Insufficient Logging in Sails with Mongodb

Insufficient Logging in Sails with Mongodb — how this specific combination creates or exposes the vulnerability

Insufficient logging in Sails applications that use MongoDB as the primary datastore can significantly hinder detection, investigation, and response to security incidents. Sails is an opinionated, MVC framework that abstracts much of the request/response lifecycle and data layer interactions. When combined with MongoDB, a schemaless document database, developers must intentionally instrument logging because neither the framework nor the database enforces it by default.

At the framework level, Sails does not automatically log every incoming request, parameter payload, or ORM-style query generated by Waterline. Without explicit configuration, important context—such as which user attempted an action, what data was submitted, and which database operation was executed—may not be recorded. This becomes especially risky when handling authentication, authorization, and sensitive data operations, where an attacker may probe for weaknesses or attempt privilege escalation.

MongoDB compounds this because operations are often asynchronous and event-driven. By default, MongoDB driver interactions do not produce structured logs that are automatically correlated with HTTP request IDs in Sails. If a BOLA (Broken Level Access) or IDOR vulnerability is exploited to read or modify another user’s records, the absence of request-to-database tracing makes it difficult to link an unauthorized document access to a specific API call. Similarly, data exposure risks—such as returning sensitive fields inadvertently—can remain undetected if query results are not logged with appropriate redaction decisions.

Inadequate logging also obscures injection and input validation issues. Malformed payloads or unexpected field structures that could trigger parsing errors or injection vectors may only surface as generic exceptions unless the application logs the raw payload and the resulting database operation outcome. Without these details, security teams cannot reliably identify patterns indicative of SSRF attempts, unauthorized function calls, or unsafe consumption of user-controlled input.

Finally, compliance and forensic readiness suffer. Controls tied to frameworks such as OWASP API Top 10 (2023) emphasize auditability, and standards like PCI-DSS, SOC 2, and GDPR expect traceability for data access and modifications. A Sails + MongoDB stack that lacks structured, centralized logging fails to meet these expectations, leaving organizations unable to produce evidence during audits or to conduct effective incident response.

Mongodb-Specific Remediation in Sails — concrete code fixes

Remediation centers on explicitly instrumenting logs at the entry point of each request and within MongoDB interaction layers. In Sails, this can be achieved through policies, custom model methods, and structured logger integrations that correlate logs with request IDs.

1. Centralized request logging with correlation IDs

Use a policy to log incoming requests, including method, URL, IP, and a unique correlation ID that is passed into MongoDB operations. This enables traceability across asynchronous calls.

// api/policies/logging.js
const { v4: uuidv4 } = require('uuid');
const { createLogger, format, transports } = require('winston');

const logger = createLogger({
  level: 'info',
  format: format.combine(
    format.timestamp(),
    format.json()
  ),
  transports: [new transports.Console()]
});

module.exports = async function (req, res, proceed) {
  const correlationId = uuidv4();
  req.correlationId = correlationId;
  logger.info('Incoming request', {
    correlationId,
    method: req.method,
    url: req.url,
    body: req.body,
    query: req.query,
    ip: req.ip
  });
  return proceed();
};

2. Instrumenting MongoDB (Waterline) operations

Override or wrap model methods to log queries and outcomes. For native MongoDB interactions, use the MongoDB driver directly while ensuring logs include the correlation ID.

// api/models/User.js
module.exports = {
  attributes: {
    email: 'string',
    role: 'string',
    ssn: 'string'
  },

  findByEmailSafe: async function (email, correlationId) {
    const MongoClient = require('mongodb').MongoClient;
    const client = new MongoClient(process.env.MONGODB_URI, { useUnifiedTopology: true });
    try {
      await client.connect();
      const db = client.db('appdb');
      console.info('[MongoDB] findByEmail', {
        correlationId,
        query: { email },
        collection: 'users'
      });
      const result = await db.collection('users').findOne({ email });
      console.info('[MongoDB] findByEmail result', {
        correlationId,
        hasResult: !!result,
        returnedFields: result ? Object.keys(result) : []
      });
      return result;
    } finally {
      await client.close();
    }
  }
};

3. Redacting sensitive fields in logs

Ensure that logs never record sensitive fields such as passwords, tokens, or PII. Apply redaction before outputting the logs.

// api/policies/logging.js (extended)
function redact(obj) {
  if (!obj) return obj;
  const redacted = { ...obj };
  if (redacted.password) redacted.password = '***REDACTED***';
  if (redacted.token) redacted.token = '***REDACTED***';
  if (redacted.ssn) redacted.ssn = '***REDACTED***';
  return redacted;
}

// Then use redact(req.body) and redact(req.query) when logging.

4. Enabling MongoDB driver logging selectively

For debugging, set the MongoDB driver logging level to 'info' or 'warn' in non-production environments only, and ensure logs are structured and include correlation IDs.

// config/db.js
module.exports.datastores = {
  default: {
    adapter: 'sails-mongo',
    url: process.env.MONGODB_URI,
    // Enable MongoDB driver logging with correlation context
    logLevel: process.env.NODE_ENV === 'development' ? 'info' : 'warn'
  }
};

Frequently Asked Questions

What are common signs of insufficient logging in a Sails + MongoDB API?
Common signs include missing request identifiers in database logs, inability to trace which user triggered an operation, absence of payload validation errors, and lack of audit trails for sensitive document reads or writes. If security events cannot be correlated to specific API calls, logging is likely insufficient.
How can I ensure logs remain useful without storing sensitive data in MongoDB logs?
Implement field-level redaction before logging any request or database payload. Use structured logging with correlation IDs, log only metadata about queries (e.g., collection name, filter keys without sensitive values), and enforce strict retention policies to prevent long-term storage of raw sensitive information.