Fix Insufficient Logging & Monitoring in Express
Insufficient logging turns a minor breach into a total catastrophe. Without a clear audit trail of authentication failures, access control violations, and server-side errors, you're effectively blind during an active exploit. In Express, default behavior logs nothing to the console or filesystem, leaving no forensic evidence for incident response. To fix this, you need structured, centralized logging that captures the 'who, what, and where' of every high-risk event.
The Vulnerable Pattern
const express = require('express'); const app = express();app.post(‘/api/login’, (req, res) => { const { username, password } = req.body; // VULNERABILITY: No logging on authentication attempts. // If a brute-force attack occurs, there is no record of the source IP or frequency. if (username !== ‘admin’ || password !== ‘secret’) { return res.status(401).send(‘Unauthorized’); } res.send(‘Success’); });
// VULNERABILITY: Generic error handler provides no telemetry to the dev team. app.use((err, req, res, next) => { res.status(500).send(‘Internal Server Error’); });
app.listen(3000);
The Secure Implementation
The secure implementation replaces silent failures with structured JSON logging using Winston and Morgan. Key improvements: 1. Structured Data: Logs are output as JSON, making them easily searchable in stacks like ELK or Splunk. 2. High-Value Events: Authentication failures now log the username and IP, enabling automated alerting for brute-force attacks. 3. Error Telemetry: The global error handler captures stack traces and request paths, ensuring developers can debug crashes without exposing sensitive internals to the user. 4. Audit Trail: Every HTTP request is piped through Morgan to provide a standard access log.
const express = require('express'); const winston = require('winston'); const morgan = require('morgan'); const app = express();// Configure structured JSON logging for SIEM ingestion const logger = winston.createLogger({ level: ‘info’, format: winston.format.json(), transports: [new winston.transports.Console()] });
// HTTP request middleware for basic traffic visibility app.use(morgan(‘combined’, { stream: { write: (msg) => logger.info(msg.trim()) } }));
app.post(‘/api/login’, (req, res) => { const { username } = req.body; const isSuccess = authenticate(req.body);
if (!isSuccess) { // SECURE: Log critical security events with metadata logger.warn({ event: ‘authentication_failure’, user: username, ip: req.ip, userAgent: req.headers[‘user-agent’], timestamp: new Date().toISOString() }); return res.status(401).send(‘Unauthorized’); } res.send(‘Success’); });
// SECURE: Centralized error handling with stack trace logging (not sent to client) app.use((err, req, res, next) => { logger.error({ message: err.message, stack: err.stack, path: req.path, method: req.method }); res.status(500).json({ error: ‘Internal Incident Logged’ }); });
app.listen(3000);
Your Express API
might be exposed to Insufficient Logging & Monitoring
74% of Express 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.