Logging Failures

This skill should be used when the user asks about "logging failures", "log injection", "insufficient logging", "audit logging", "security logging", "CWE-117", or needs to find logging-related vulnerabilities during whitebox security review.

14 stars

Best use case

Logging Failures is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

This skill should be used when the user asks about "logging failures", "log injection", "insufficient logging", "audit logging", "security logging", "CWE-117", or needs to find logging-related vulnerabilities during whitebox security review.

Teams using Logging Failures should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/logging-failures/SKILL.md --create-dirs "https://raw.githubusercontent.com/allsmog/vuln-scout/main/vuln-scout/skills/logging-failures/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/logging-failures/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How Logging Failures Compares

Feature / AgentLogging FailuresStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

This skill should be used when the user asks about "logging failures", "log injection", "insufficient logging", "audit logging", "security logging", "CWE-117", or needs to find logging-related vulnerabilities during whitebox security review.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Logging & Alerting Failures (OWASP A09)

## Purpose

Provide detection patterns for logging vulnerabilities including log injection, insufficient logging of security events, secrets in logs, and log tampering vulnerabilities.

## OWASP Top 10 Mapping

**Category**: A09 - Security Logging & Alerting Failures

**CWEs**:
- CWE-117: Improper Output Neutralization for Logs
- CWE-223: Omission of Security-Relevant Information
- CWE-532: Insertion of Sensitive Information into Log File
- CWE-778: Insufficient Logging

## When to Use

Activate this skill when:
- Reviewing logging implementations
- Checking for log injection vulnerabilities
- Auditing security event logging
- Looking for secrets exposed in logs
- Verifying audit trail completeness

---

## Log Injection (CWE-117)

### Overview

Log injection occurs when user-controlled input is written to logs without sanitization, allowing attackers to inject fake log entries or manipulate log output.

### Detection Patterns

#### Python

```bash
# String concatenation in logs
grep -rniE "logging\.(info|debug|error|warn).*\+|logger\.(info|debug|error|warn).*\+" --include="*.py"

# f-string/format in logs with user input
grep -rniE "logging\.(info|debug|error|warn).*f['\"]|logger\..*\.format\(" --include="*.py"
```

**Vulnerable**:
```python
# VULNERABLE: User input directly in log
logger.info(f"User login: {request.form['username']}")  # Can inject newlines
```

**Secure**:
```python
# SAFE: Structured logging
logger.info("User login", extra={"username": sanitize(username)})
```

#### Java

```bash
# String concatenation in logs
grep -rniE "log\.(info|debug|error|warn).*\+|logger\.(info|debug|error|warn).*\+" --include="*.java"

# Format with user input
grep -rniE "String\.format.*log|log.*String\.format" --include="*.java"
```

**Vulnerable**:
```java
// VULNERABLE: Direct concatenation
logger.info("User login: " + username);  // Can inject newlines
```

**Secure**:
```java
// SAFE: Parameterized logging
logger.info("User login: {}", sanitize(username));
```

#### Go

```bash
# Printf-style logging with user input
grep -rniE "log\.Printf|log\.Print.*\+" --include="*.go"

# Zap/logrus with user input
grep -rniE "zap\.String.*request|logrus\.WithField.*request" --include="*.go"
```

**Vulnerable**:
```go
// VULNERABLE: Direct formatting
log.Printf("User login: %s", userInput)  // Can inject newlines
```

**Secure**:
```go
// SAFE: Structured logging
logger.Info("user login", zap.String("username", sanitize(username)))
```

#### TypeScript

```bash
# Console/logger with concatenation
grep -rniE "console\.(log|info|error|warn).*\+|logger\.(log|info|error|warn).*\+" --include="*.ts"
```

#### PHP

```bash
# error_log with user input
grep -rniE "error_log.*\$_|syslog.*\$_|log.*\$_(GET|POST|REQUEST)" --include="*.php"
```

### Log Injection Payloads

```
# Inject fake log entry
username: legitimate_user\n[ERROR] Admin password changed by attacker

# Inject multiple lines
input: line1\n[INFO] Fake entry\n[DEBUG] More fake entries

# ANSI escape codes (terminal injection)
input: \x1b[2J\x1b[1;1H  # Clear terminal
```

---

## Insufficient Logging (CWE-778)

### Overview

Missing logs for security-critical events prevents detection of attacks and incident response.

### Events That MUST Be Logged

| Event Category | Specific Events |
|----------------|-----------------|
| **Authentication** | Login success/failure, logout, password change |
| **Authorization** | Access denied, privilege escalation attempts |
| **Input Validation** | Rejected/suspicious input |
| **Session** | Session creation, destruction, timeout |
| **Data Access** | Sensitive data read/write/delete |
| **Configuration** | Settings changes, feature toggles |
| **Errors** | Exceptions, failures (without stack traces) |

### Detection Patterns

```bash
# Find auth functions without logging
grep -rniE "def (login|authenticate|authorize|check_permission)" --include="*.py" -A 10 | grep -v "log\."

# Find exception handlers without logging
grep -rniE "except.*:|catch\s*\(" --include="*.py" --include="*.java" -A 5 | grep -v "log\|logger"

# Find permission checks without logging
grep -rniE "has_permission|is_admin|check_role" --include="*.go" --include="*.py" --include="*.java" -A 5 | grep -v "log"
```

### What to Check

```bash
# Authentication logging
grep -rniE "login|authenticate|logout" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" | xargs -I {} sh -c 'grep -l "log" {} || echo "MISSING: {}"'

# Failed access logging
grep -rniE "forbidden|unauthorized|access.*denied" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"

# Data modification logging
grep -rniE "delete|update|insert" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" | xargs -I {} sh -c 'grep -l "log\|audit" {} || echo "MISSING: {}"'
```

---

## Secrets in Logs (CWE-532)

### Overview

Logging sensitive data (passwords, tokens, API keys) exposes them to anyone with log access.

### Detection Patterns

```bash
# Password in logs
grep -rniE "log.*(password|passwd|pwd|secret|token|api_key|apikey|credential)" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"

# Request body logging (may contain secrets)
grep -rniE "log.*request\.body|log.*req\.body|log.*getBody" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"

# Full object logging
grep -rniE "log.*user\)|log.*%v.*user|log.*JSON\.stringify" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
```

### Sensitive Fields to Never Log

- `password`, `passwd`, `pwd`
- `token`, `access_token`, `refresh_token`
- `api_key`, `apikey`, `secret_key`
- `credit_card`, `ccn`, `cvv`
- `ssn`, `social_security`
- `private_key`, `secret`
- Authorization headers
- Session IDs

### Secure Pattern - Field Redaction

```python
# Python - Redact sensitive fields
SENSITIVE_FIELDS = ['password', 'token', 'api_key', 'secret']

def redact_sensitive(data: dict) -> dict:
    return {k: '***REDACTED***' if k.lower() in SENSITIVE_FIELDS else v
            for k, v in data.items()}

logger.info("User data", extra=redact_sensitive(user_data))
```

```go
// Go - Redact sensitive fields
func redactSensitive(data map[string]interface{}) map[string]interface{} {
    sensitive := []string{"password", "token", "api_key"}
    for _, key := range sensitive {
        if _, exists := data[key]; exists {
            data[key] = "***REDACTED***"
        }
    }
    return data
}
```

---

## Log Tampering

### Overview

If logs can be modified or deleted, attackers can cover their tracks.

### Detection Patterns

```bash
# Predictable log file paths
grep -rniE "logfile\s*=|LOG_FILE\s*=|log_path\s*=" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php" --include="*.env"

# User-controlled log paths
grep -rniE "log.*request\.(path|param|query)" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"

# Log rotation without integrity
grep -rniE "RotatingFileHandler|logrotate|rotate.*log" --include="*.go" --include="*.py" --include="*.java" --include="*.conf"
```

### Secure Patterns

- Write logs to append-only storage
- Use centralized logging (SIEM)
- Implement log integrity verification (signing)
- Restrict log file permissions
- Use remote logging to prevent local tampering

---

## Missing Alerting

### Overview

Logs without alerts allow attacks to go unnoticed.

### Events That Should Alert

| Event | Alert Priority |
|-------|----------------|
| Multiple failed logins | HIGH |
| Admin actions | MEDIUM |
| Privilege escalation | CRITICAL |
| Sensitive data access | HIGH |
| Configuration changes | MEDIUM |
| Error rate spike | HIGH |
| Unusual access patterns | MEDIUM |

### Detection Patterns

```bash
# Check for alerting configuration
grep -rniE "alert|notify|pagerduty|slack.*webhook|email.*notify" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.yaml" --include="*.json"

# Check for threshold-based alerts
grep -rniE "threshold|rate_limit|max_attempts|lockout" --include="*.go" --include="*.py" --include="*.java" --include="*.ts" --include="*.php"
```

---

## Language-Specific Secure Logging

### Python (structlog)

```python
import structlog

logger = structlog.get_logger()

# Structured with automatic sanitization
logger.info(
    "user_login",
    username=sanitize(username),
    ip_address=request.remote_addr,
    success=True
)
```

### Java (SLF4J + Logback)

```java
// Use MDC for structured context
MDC.put("userId", sanitize(userId));
MDC.put("action", "login");
logger.info("User authentication successful");
MDC.clear();
```

### Go (Zap)

```go
logger.Info("user authentication",
    zap.String("user_id", sanitize(userID)),
    zap.String("action", "login"),
    zap.Bool("success", true),
)
```

### TypeScript (Winston)

```typescript
logger.info('user authentication', {
    userId: sanitize(userId),
    action: 'login',
    success: true,
    timestamp: new Date().toISOString()
});
```

---

## Log Format Requirements

A secure log entry should include:

| Field | Purpose |
|-------|---------|
| Timestamp | When (ISO 8601) |
| Level | Severity (INFO, WARN, ERROR) |
| Source | Where (service, file, function) |
| User | Who (user ID, not PII) |
| Action | What happened |
| Resource | What was accessed |
| Outcome | Success/failure |
| Request ID | Correlation |
| IP Address | Origin |

### Example Secure Log Format

```json
{
  "timestamp": "2025-01-15T10:30:00Z",
  "level": "INFO",
  "service": "auth-service",
  "event": "user_login",
  "user_id": "usr_12345",
  "action": "authenticate",
  "outcome": "success",
  "request_id": "req_abc123",
  "ip_address": "192.168.1.1",
  "user_agent": "Mozilla/5.0..."
}
```

---

## Verification Checklist

- [ ] Log injection prevented (sanitized input)
- [ ] Authentication events logged
- [ ] Authorization failures logged
- [ ] Data access logged
- [ ] Sensitive data redacted
- [ ] Logs written to secure location
- [ ] Log integrity protected
- [ ] Alerting configured for critical events
- [ ] Log retention policy defined

---

## CWE References

| CWE | Name | Example |
|-----|------|---------|
| CWE-117 | Log Injection | Newlines in log messages |
| CWE-223 | Omission of Info | Missing auth failure logs |
| CWE-532 | Secrets in Logs | Passwords logged |
| CWE-778 | Insufficient Logging | No audit trail |

Related Skills

We are still matching the closest adjacent skills for this page. In the meantime, continue through the full directory.