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'
}
};