Fix Insufficient Logging & Monitoring in Sails
Sails.js defaults are dangerously silent. If you aren't logging auth failures, input validation drops, and internal server errors with full context, you're flying blind. Real-world monitoring requires structured data, not just console spam. This guide hardens your Sails app by integrating Winston for high-fidelity telemetry and ensuring critical security events are never missed.
The Vulnerable Pattern
module.exports = {
login: async function (req, res) {
const user = await User.findOne({ email: req.body.email });
if (!user || user.password !== req.body.password) {
// VULNERABILITY: Silent failure. No log entry created.
// An attacker can brute-force this endpoint without leaving a trace.
return res.forbidden();
}
req.session.userId = user.id;
return res.ok();
}
};
The Secure Implementation
The fix involves three pillars: Structured Logging, Contextual Metadata, and Appropriate Levels. By overriding the default Sails logger with Winston, we output logs in JSON format, which is easily ingested by SIEMs like ELK or Splunk. In the secure snippet, we log every failed login attempt with the 'warn' level, capturing the attacker's IP and User-Agent. This enables automated alerting for brute-force patterns. Successful logins and system errors are also logged with enough context to reconstruct a timeline during incident response, fulfilling OWASP A09:2021 requirements.
// config/log.js configuration const winston = require('winston'); module.exports.log = { custom: winston.createLogger({ level: 'info', format: winston.format.combine(winston.format.timestamp(), winston.format.json()), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: 'logs/security.log', level: 'warn' }) ] }), inspect: false };// api/controllers/AuthController.js module.exports = { login: async function (req, res) { const { email } = req.body; try { const user = await User.findOne({ email }); if (!user || !await sails.helpers.passwords.checkPassword(req.body.password, user.password)) { sails.log.warn({ event: ‘LOGIN_FAILURE’, target_user: email, ip: req.ip, ua: req.headers[‘user-agent’], timestamp: new Date().toISOString() }); return res.badRequest(‘Invalid credentials’); }
sails.log.info({ event: 'LOGIN_SUCCESS', user_id: user.id, ip: req.ip }); req.session.userId = user.id; return res.ok(); } catch (err) { sails.log.error({ event: 'AUTH_SYSTEM_ERROR', error: err.message, stack: err.stack }); return res.serverError(); }
} };
Your Sails API
might be exposed to Insufficient Logging & Monitoring
74% of Sails apps fail this check. Hackers use automated scanners to find this specific flaw. Check your codebase before they do.
Free Tier • No Credit Card • Instant Report
Verified by Ghost Labs Security Team
This content is continuously validated by our automated security engine and reviewed by our research team. Ghost Labs analyzes over 500+ vulnerability patterns across 40+ frameworks to provide up-to-date remediation strategies.