Log Injection with Api Keys
How Log Injection Manifests in Api Keys
Log injection in API keys represents a critical security vulnerability where malicious actors exploit logging mechanisms to inject arbitrary data, potentially exposing sensitive credentials or creating deceptive audit trails. In API key contexts, this manifests through several specific attack vectors that target the intersection of authentication mechanisms and logging infrastructure.
The most common pattern involves attackers crafting API keys that contain log injection payloads. When these keys are processed by logging systems, the malicious content gets written directly to log files, potentially exposing other users' API keys, session tokens, or sensitive request data. Consider this vulnerable logging pattern:
const logRequest = (req) => {
const apiKey = req.headers['x-api-key'] || 'no-key';
console.log(`API Key: ${apiKey} - Endpoint: ${req.path}`);
};
// Malicious API key: "key123" + " - Endpoint: /admin - API Key: secret-admin-key"
// Resulting log: "API Key: key123 - Endpoint: /admin - API Key: secret-admin-key - Endpoint: /users"
This demonstrates how log injection can cause credential leakage through log file contamination. The attacker's API key contains log formatting characters that break the intended log structure, causing legitimate API keys to be exposed in subsequent log entries.
Another manifestation occurs in multi-tenant systems where API keys serve as tenant identifiers. Attackers can inject log entries that appear to originate from other tenants, creating confusion during incident investigations or even framing other users for malicious activity. This is particularly dangerous in systems that use API keys for both authentication and audit trail purposes.
Structured logging systems are also vulnerable when API keys are included in log contexts without proper sanitization. JSON log structures can be broken when API keys contain special characters like quotes, brackets, or newlines:
const structuredLog = {
timestamp: new Date(),
apiKey: req.headers['x-api-key'], // Contains: "key"}
user: 'attacker',
action: 'login'
};
// Resulting log: {"timestamp":"2024-01-01T00:00:00.000Z","apiKey":"key"}
user":"attacker","action":"login"}
This breaks the JSON structure, potentially causing log parsing failures or creating ambiguous audit trails where malicious activity becomes indistinguishable from legitimate requests.
Api Keys-Specific Detection
Detecting log injection in API key contexts requires a multi-layered approach that combines static analysis, runtime monitoring, and automated scanning. middleBrick's API security scanner includes specialized checks for log injection vulnerabilities that are particularly relevant to API key implementations.
Static code analysis should focus on identifying logging statements that directly incorporate API key values without sanitization. Look for patterns where API keys are concatenated into log messages or included in structured logging contexts:
# Using middleBrick CLI to scan for log injection vulnerabilities
middlebrick scan https://api.example.com --test=log-injection --output=json
# Results include:
# - Authentication bypass via log injection
# - Credential exposure in logs
# - Structured log corruption
Runtime detection involves monitoring log files for anomalous patterns that indicate injection attempts. This includes:
- Unexpected JSON structure breaks or log format violations
- Multiple API keys appearing in single log entries
- Log entries containing suspicious metadata like timestamps or user identifiers that don't match the request context
- Log rotation failures or parsing errors that correlate with specific API key patterns
middleBrick's black-box scanning approach tests the unauthenticated attack surface by sending API requests with specially crafted API keys designed to trigger log injection vulnerabilities. The scanner analyzes the resulting log output (where accessible) or monitors for indicators like increased error rates, unexpected log structure changes, or authentication anomalies.
For API key management systems, specific detection strategies include:
// API key validation with log injection detection
function validateApiKey(apiKey: string): boolean {
// Check for common log injection patterns
const injectionPatterns = [
/\n/g, // Newline characters
/\t/g, // Tab characters
/\r/g, // Carriage return
/\{/g, // Curly braces
/\}/g, // Curly braces
/"/g, // Double quotes
/'//g, // Single quotes
//g, // Greater than
];
if (injectionPatterns.some(pattern => pattern.test(apiKey))) {
console.warn('Potential log injection detected in API key:', apiKey);
return false;
}
return true;
}
This validation function can be integrated into API key validation middleware to prevent log injection at the point of entry.
Api Keys-Specific Remediation
Remediating log injection vulnerabilities in API key implementations requires a defense-in-depth approach that combines input validation, output encoding, and architectural changes to logging practices. The goal is to prevent malicious API keys from compromising log integrity while maintaining useful audit trails.
The first line of defense is API key validation and sanitization before any logging occurs. Implement strict validation rules that reject API keys containing characters that could break log structures:
// API key sanitization middleware
const sanitizeApiKey = (apiKey) => {
// Remove or replace characters that could break log structures
return apiKey
.replace(/\n/g, '') // Remove newlines
.replace(/\t/g, '') // Remove tabs
.replace(/"/g, '"') // Replace quotes
.replace(/'//g, ''') // Replace single quotes
.replace(//g, '>') // Replace angle brackets
.substring(0, 64); // Truncate to reasonable length
};
// Enhanced logging function
const secureLogRequest = (req) => {
const apiKey = req.headers['x-api-key'];
const sanitizedKey = sanitizeApiKey(apiKey || 'no-key');
// Use structured logging with explicit field separation
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
endpoint: req.path,
method: req.method,
apiKey: sanitizedKey,
userAgent: req.headers['user-agent']
}));
};
For systems using structured logging, implement strict schema validation to prevent malformed log entries. This ensures that even if injection attempts occur, they cannot break the log structure:
const Joi = require('joi');
const logSchema = Joi.object({
timestamp: Joi.date().required(),
apiKey: Joi.string().max(64).required(),
endpoint: Joi.string().uri().required(),
method: Joi.string().valid('GET', 'POST', 'PUT', 'DELETE', 'PATCH').required(),
userId: Joi.string().optional()
});
const validateAndLog = (logData) => {
const { error } = logSchema.validate(logData);
if (error) {
console.error('Invalid log data:', error.details);
return;
}
console.log(JSON.stringify(logData));
};
Implement API key rotation policies that invalidate keys containing suspicious patterns. This prevents attackers from maintaining persistent injection capabilities through compromised API keys:
# API key rotation with injection detection
class ApiKeyManager:
def __init__(self):
self.api_keys = {}
self.injection_patterns = [
r'\n', r'\t', r'\r', r'\{', r'\}', r'"', r"'", r'<', r'>'
]
def generate_key(self, user_id):
# Generate secure random key
key = secrets.token_urlsafe(32)
# Check for injection patterns
if any(re.search(pattern, key) for pattern in self.injection_patterns):
# Regenerate if patterns detected
return self.generate_key(user_id)
self.api_keys[key] = {
'user_id': user_id,
'created': datetime.now(),
'valid': True
}
return key
def validate_key(self, key):
# Check for injection patterns before validation
if any(re.search(pattern, key) for pattern in self.injection_patterns):
return False
return self.api_keys.get(key, {}).get('valid', False)
Finally, implement comprehensive log monitoring that can detect injection attempts in real-time. This includes alerting on anomalous log patterns, unexpected API key formats, or authentication failures that correlate with specific API key patterns.