Real-Time Security Monitoring
Real-Time Security Monitoring
Real-time monitoring enables rapid detection and response to security incidents. Effective monitoring combines multiple data sources, applies intelligent analysis, and generates actionable alerts without overwhelming security teams with false positives.
// Node.js real-time security monitoring system
const EventEmitter = require('events');
const Redis = require('redis');
const { InfluxDB, Point } = require('@influxdata/influxdb-client');
class SecurityMonitor extends EventEmitter {
constructor(config) {
super();
this.config = config;
this.redis = Redis.createClient(config.redis);
this.influx = new InfluxDB(config.influxdb);
this.writeApi = this.influx.getWriteApi(config.org, config.bucket);
this.patterns = new Map();
this.alerts = new Map();
this.initializePatterns();
}
initializePatterns() {
// Define security patterns to monitor
this.patterns.set('brute_force', {
window: 300, // 5 minutes
threshold: 10,
key: (event) => `auth_failure:${event.ip_address}`,
condition: (event) => event.event_type === 'authentication' && !event.success
});
this.patterns.set('credential_stuffing', {
window: 600, // 10 minutes
threshold: 5,
key: (event) => `auth_attempt:${event.ip_address}:unique_users`,
condition: (event) => event.event_type === 'authentication'
});
this.patterns.set('api_scanning', {
window: 60, // 1 minute
threshold: 50,
key: (event) => `404_errors:${event.ip_address}`,
condition: (event) => event.status_code === 404
});
this.patterns.set('privilege_escalation', {
window: 3600, // 1 hour
threshold: 3,
key: (event) => `priv_escalation:${event.user_id}`,
condition: (event) => event.event_type === 'authorization' &&
!event.granted &&
event.missing_permissions?.includes('admin')
});
this.patterns.set('data_exfiltration', {
window: 300, // 5 minutes
threshold: 1000000, // 1MB
key: (event) => `data_transfer:${event.user_id}`,
condition: (event) => event.event_type === 'api_response',
value: (event) => event.response_size || 0
});
}
async processEvent(event) {
// Enrich event with additional context
event = await this.enrichEvent(event);
// Check against all patterns
for (const [patternName, pattern] of this.patterns) {
if (pattern.condition(event)) {
await this.updatePattern(patternName, pattern, event);
}
}
// Store metrics
await this.storeMetrics(event);
// Check for anomalies
await this.detectAnomalies(event);
}
async updatePattern(patternName, pattern, event) {
const key = pattern.key(event);
const value = pattern.value ? pattern.value(event) : 1;
// Update counter in Redis
const multi = this.redis.multi();
if (patternName === 'credential_stuffing') {
// Track unique usernames per IP
multi.sadd(key, event.username);
multi.expire(key, pattern.window);
const results = await multi.exec();
const uniqueUsers = await this.redis.scard(key);
if (uniqueUsers >= pattern.threshold) {
await this.triggerAlert('credential_stuffing', {
ip_address: event.ip_address,
unique_users_attempted: uniqueUsers,
window: pattern.window
});
}
} else {
// Standard counter pattern
multi.incrby(key, value);
multi.expire(key, pattern.window);
const results = await multi.exec();
const currentValue = results[0][1];
if (currentValue >= pattern.threshold) {
await this.triggerAlert(patternName, {
...event,
current_value: currentValue,
threshold: pattern.threshold,
window: pattern.window
});
}
}
}
async detectAnomalies(event) {
// User behavior anomaly detection
if (event.user_id) {
const userProfile = await this.getUserProfile(event.user_id);
const anomalyScore = this.calculateAnomalyScore(event, userProfile);
if (anomalyScore > 0.8) {
await this.triggerAlert('behavior_anomaly', {
user_id: event.user_id,
anomaly_score: anomalyScore,
event: event,
baseline: userProfile
});
}
}
// Geographic anomaly detection
if (event.ip_address && event.user_id) {
const isGeoAnomaly = await this.detectGeographicAnomaly(
event.user_id,
event.ip_address
);
if (isGeoAnomaly) {
await this.triggerAlert('geographic_anomaly', {
user_id: event.user_id,
ip_address: event.ip_address,
location: event.geo_location
});
}
}
}
async triggerAlert(alertType, details) {
// Deduplication
const alertKey = `${alertType}:${JSON.stringify(details)}`;
const recentAlert = this.alerts.get(alertKey);
if (recentAlert && Date.now() - recentAlert < 300000) { // 5 min
return; // Skip duplicate alerts
}
this.alerts.set(alertKey, Date.now());
// Emit alert event
this.emit('security_alert', {
type: alertType,
severity: this.getAlertSeverity(alertType),
details: details,
timestamp: new Date().toISOString(),
recommended_actions: this.getRecommendedActions(alertType)
});
// Store alert
await this.storeAlert(alertType, details);
// Automated response for critical alerts
if (this.shouldAutoRespond(alertType)) {
await this.executeAutoResponse(alertType, details);
}
}
async executeAutoResponse(alertType, details) {
switch (alertType) {
case 'brute_force':
// Temporarily block IP
await this.blockIP(details.ip_address, 3600); // 1 hour
break;
case 'credential_stuffing':
// Enable CAPTCHA for IP
await this.enableCaptcha(details.ip_address);
break;
case 'api_scanning':
// Rate limit IP more aggressively
await this.tightenRateLimit(details.ip_address);
break;
case 'data_exfiltration':
// Suspend user account for review
await this.suspendUser(details.user_id);
break;
}
}
async storeMetrics(event) {
// Write to InfluxDB for time-series analysis
const point = new Point('api_security_events')
.tag('event_type', event.event_type)
.tag('service', this.config.service_name)
.tag('environment', this.config.environment);
if (event.user_id) {
point.tag('user_id', event.user_id);
}
if (event.status_code) {
point.intField('status_code', event.status_code);
}
if (event.response_time_ms) {
point.floatField('response_time_ms', event.response_time_ms);
}
if (event.risk_score) {
point.floatField('risk_score', event.risk_score);
}
this.writeApi.writePoint(point);
}
}
// Integration with Express middleware
const securityMonitor = new SecurityMonitor(config);
// Alert handler
securityMonitor.on('security_alert', async (alert) => {
console.error('Security Alert:', alert);
// Send to SIEM
await siemClient.sendAlert(alert);
// Notify security team
if (alert.severity === 'CRITICAL') {
await notificationService.pageSecurity(alert);
} else {
await notificationService.emailSecurity(alert);
}
});
// Middleware for automatic monitoring
app.use(async (req, res, next) => {
const startTime = Date.now();
// Capture response data
const originalSend = res.send;
res.send = function(data) {
res.responseData = data;
originalSend.call(this, data);
};
res.on('finish', async () => {
const event = {
event_type: 'api_request',
method: req.method,
path: req.path,
status_code: res.statusCode,
response_time_ms: Date.now() - startTime,
response_size: res.get('content-length'),
ip_address: req.ip,
user_id: req.user?.id,
user_agent: req.get('user-agent')
};
await securityMonitor.processEvent(event);
});
next();
});