Claude
Skills
Sign in
Back

logging-monitoring

Included with Lifetime
$97 forever

OWASP A10 - Insufficient Logging and Monitoring. Use this skill when implementing audit logs, security monitoring, or incident detection. Activate when: logging, audit trail, security events, monitoring, alerting, SIEM, incident detection, log analysis, security logging, breach detection.

Security

What this skill does


# Security Logging & Monitoring (OWASP A10)

**Implement comprehensive logging and monitoring to detect and respond to security incidents.**

## When to Use

- Setting up application logging
- Implementing audit trails
- Configuring security alerting
- Building incident detection
- Compliance requirements (SOC2, GDPR)
- Post-incident forensics

## Critical Events to Log

| Event Category | Examples | Priority |
|---------------|----------|----------|
| Authentication | Login success/failure, logout, MFA events | HIGH |
| Authorization | Access denied, privilege changes | HIGH |
| Data Access | Sensitive data reads, exports | HIGH |
| Data Modification | Create, update, delete operations | MEDIUM |
| Security Events | Input validation failures, rate limits | HIGH |
| System Events | Startup, shutdown, errors | MEDIUM |
| Admin Actions | Config changes, user management | HIGH |

## What NOT to Log

```javascript
// NEVER log these:
const NEVER_LOG = [
  'passwords',
  'credit_card_numbers',
  'ssn',
  'api_keys',
  'tokens',
  'session_ids',
  'private_keys',
  'health_information'
];
```

## Secure Logging Implementation

### 1. Structured Security Logger

```javascript
const winston = require('winston');

// Security event types
const SecurityEventType = {
  AUTH_SUCCESS: 'AUTH_SUCCESS',
  AUTH_FAILURE: 'AUTH_FAILURE',
  AUTH_LOGOUT: 'AUTH_LOGOUT',
  ACCESS_DENIED: 'ACCESS_DENIED',
  PRIVILEGE_ESCALATION: 'PRIVILEGE_ESCALATION',
  DATA_ACCESS: 'DATA_ACCESS',
  DATA_EXPORT: 'DATA_EXPORT',
  INPUT_VALIDATION_FAILURE: 'INPUT_VALIDATION_FAILURE',
  RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
  SUSPICIOUS_ACTIVITY: 'SUSPICIOUS_ACTIVITY',
  ADMIN_ACTION: 'ADMIN_ACTION',
  CONFIG_CHANGE: 'CONFIG_CHANGE'
};

// Security logger configuration
const securityLogger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp({ format: 'ISO' }),
    winston.format.json()
  ),
  defaultMeta: {
    service: 'my-app',
    environment: process.env.NODE_ENV
  },
  transports: [
    // Security events to dedicated file
    new winston.transports.File({
      filename: 'logs/security.log',
      level: 'info'
    }),
    // Critical events to separate file
    new winston.transports.File({
      filename: 'logs/security-critical.log',
      level: 'warn'
    }),
    // Send to SIEM (example: Splunk HEC)
    new winston.transports.Http({
      host: 'splunk.example.com',
      port: 8088,
      path: '/services/collector',
      ssl: true
    })
  ]
});

// Log security event function
function logSecurityEvent(eventType, details) {
  const event = {
    eventType,
    timestamp: new Date().toISOString(),
    ...sanitizeForLogging(details)
  };

  // Determine log level based on event type
  const criticalEvents = [
    SecurityEventType.AUTH_FAILURE,
    SecurityEventType.ACCESS_DENIED,
    SecurityEventType.PRIVILEGE_ESCALATION,
    SecurityEventType.SUSPICIOUS_ACTIVITY
  ];

  if (criticalEvents.includes(eventType)) {
    securityLogger.warn(event);
  } else {
    securityLogger.info(event);
  }

  return event;
}
```

### 2. Authentication Event Logging

```javascript
// Login attempt logging
async function handleLogin(req, res) {
  const { email, password } = req.body;
  const clientIp = req.ip;
  const userAgent = req.headers['user-agent'];

  try {
    const user = await authenticateUser(email, password);

    logSecurityEvent(SecurityEventType.AUTH_SUCCESS, {
      userId: user.id,
      email: maskEmail(email),
      ip: clientIp,
      userAgent,
      method: 'password',
      mfaUsed: false
    });

    // Continue with login...
  } catch (error) {
    logSecurityEvent(SecurityEventType.AUTH_FAILURE, {
      email: maskEmail(email),
      ip: clientIp,
      userAgent,
      reason: error.code,  // e.g., 'INVALID_PASSWORD', 'USER_NOT_FOUND'
      attemptCount: await getFailedAttemptCount(email)
    });

    // Don't reveal if user exists
    res.status(401).json({ error: 'Invalid credentials' });
  }
}

// Logout logging
function handleLogout(req, res) {
  logSecurityEvent(SecurityEventType.AUTH_LOGOUT, {
    userId: req.user.id,
    sessionDuration: Date.now() - req.session.loginTime,
    ip: req.ip
  });

  req.session.destroy();
  res.json({ success: true });
}
```

### 3. Authorization Event Logging

```javascript
// Access control logging middleware
function logAccessControl(req, res, next) {
  const originalJson = res.json.bind(res);

  res.json = (body) => {
    // Log access denied
    if (res.statusCode === 403) {
      logSecurityEvent(SecurityEventType.ACCESS_DENIED, {
        userId: req.user?.id,
        path: req.path,
        method: req.method,
        ip: req.ip,
        requiredRole: req.requiredRole,
        userRole: req.user?.role
      });
    }

    return originalJson(body);
  };

  next();
}

// Privilege change logging
async function changeUserRole(adminId, targetUserId, newRole) {
  const oldRole = await getUserRole(targetUserId);

  await updateUserRole(targetUserId, newRole);

  logSecurityEvent(SecurityEventType.ADMIN_ACTION, {
    action: 'ROLE_CHANGE',
    adminId,
    targetUserId,
    oldRole,
    newRole,
    timestamp: new Date().toISOString()
  });
}
```

### 4. Data Access Logging

```javascript
// Sensitive data access logging
async function getSensitiveUserData(requesterId, targetUserId) {
  const data = await db.users.findById(targetUserId, {
    include: ['ssn', 'taxId', 'bankAccount']
  });

  logSecurityEvent(SecurityEventType.DATA_ACCESS, {
    requesterId,
    targetUserId,
    dataType: 'sensitive_pii',
    fields: ['ssn', 'taxId', 'bankAccount'],
    reason: 'customer_support_request',
    ticketId: 'TICKET-123'
  });

  return data;
}

// Data export logging
async function exportUserData(adminId, filters) {
  const recordCount = await db.users.count(filters);

  logSecurityEvent(SecurityEventType.DATA_EXPORT, {
    adminId,
    exportType: 'user_data',
    filters: sanitizeForLogging(filters),
    recordCount,
    format: 'csv'
  });

  return generateExport(filters);
}
```

### 5. Input Validation Failure Logging

```javascript
// Log validation failures (potential attack indicators)
function validateAndLog(schema, data, req) {
  const result = schema.validate(data);

  if (result.error) {
    logSecurityEvent(SecurityEventType.INPUT_VALIDATION_FAILURE, {
      path: req.path,
      method: req.method,
      ip: req.ip,
      userId: req.user?.id,
      validationErrors: result.error.details.map(d => ({
        field: d.path.join('.'),
        message: d.message,
        // Don't log the actual invalid value (might be attack payload)
        valueLength: String(d.context?.value).length
      }))
    });
  }

  return result;
}
```

### 6. Rate Limiting & Suspicious Activity

```javascript
// Rate limit exceeded logging
const rateLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  handler: (req, res) => {
    logSecurityEvent(SecurityEventType.RATE_LIMIT_EXCEEDED, {
      ip: req.ip,
      path: req.path,
      userId: req.user?.id,
      windowMs: 15 * 60 * 1000,
      requestCount: req.rateLimit.current
    });

    res.status(429).json({ error: 'Too many requests' });
  }
});

// Suspicious activity detection
function detectSuspiciousActivity(req) {
  const indicators = [];

  // Multiple failed logins
  if (req.failedLoginCount > 5) {
    indicators.push('multiple_failed_logins');
  }

  // Unusual user agent
  if (!req.headers['user-agent'] || req.headers['user-agent'].includes('sqlmap')) {
    indicators.push('suspicious_user_agent');
  }

  // Geographic anomaly
  if (req.geoLocation !== req.user?.lastKnownLocation) {
    indicators.push('geographic_anomaly');
  }

  if (indicators.length > 0) {
    logSecurityEvent(SecurityEventType.SUSPICIOUS_ACTIVITY, {
      userId: req.user?.id,
      ip: req.ip,
      indicators,
      path: req.path
    });
  }
}
```

### 7. Alerting Configuration

```javascript
// Alert on critical security events
const al

Related in Security