HIGH log injectionfastapihmac signatures

Log Injection in Fastapi with Hmac Signatures

Log Injection in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Log injection occurs when untrusted data is written into application logs without proper sanitization, enabling log forging or log injection attacks that can obscure attacker activity or trigger log-based security controls. In FastAPI applications that use HMAC signatures for request integrity and authentication, log injection can emerge from two dimensions: the application logging data derived from signed payloads, and the way signature verification logic is recorded.

Consider a FastAPI endpoint that validates an HMAC signature included in a request header and then logs details from the authenticated payload. If the payload includes user-controlled fields such as username, action, or resource, and these values are written directly into logs without sanitization, an attacker can inject newline characters or structured log delimiters to forge log entries. For example, a crafted payload can produce log lines that appear to originate from a different user or that inject fake events into audit trails.

HMAC signatures themselves do not prevent log injection; they ensure integrity and authenticity of the signed content. If the application logs the signature value or parts of the signed message without care, it may inadvertently expose sensitive data or structured tokens in logs. Moreover, if verification failures are logged with detailed exception messages or stack traces, attackers can probe differences in log output to infer whether a signature was valid, aiding tampering or side-channel analysis.

In FastAPI, a common pattern decodes and verifies an HMAC before processing business logic. If the verification logic logs the decoded payload or the signature verbatim, and the payload includes unescaped user input, the log line can be manipulated. For instance, an attacker can embed carriage returns or control characters in a string field, causing the log entry to span multiple lines and potentially bypass log parsers or SIEM rules that rely on line-based ingestion.

Real-world impacts include log forging to hide malicious actions, injection of misleading entries that trigger automated alerts, and exposure of sensitive identifiers through verbose logging. While HMAC ensures that a tampered payload is rejected, insecure logging of verified data still weakens auditability. Mitigations focus on strict input validation for log-worthy fields, structured and sanitized log formats, and avoiding logging raw signatures or sensitive payload components.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

To mitigate log injection when using HMAC signatures in FastAPI, ensure that all data written to logs is sanitized, and that logging does not expose raw signatures or sensitive payload content. Below are concrete, working examples that demonstrate secure handling.

First, use a utility to sanitize strings before logging, escaping newlines and control characters:

import re
def sanitize_for_log(value: str) -> str:
    # Replace newlines and control characters to prevent log injection
    return re.sub(r'[\r\n\x00-\x1f\x7f]', '?', value)

Second, structure your HMAC verification and logging so that only safe, normalized data is recorded:

from fastapi import FastAPI, Header, HTTPException
import hmac
import hashlib
import logging

logger = logging.getLogger(__name__)
app = FastAPI()

SECRET = b'super-secret-key'

def verify_hmac(payload: bytes, signature: str) -> bool:
    computed = hmac.new(SECRET, payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(computed, signature)

@app.post('/action')
async def perform_action(payload: str, signature: str = Header(...)):
    if not verify_hmac(payload.encode('utf-8'), signature):
        logger.warning('Signature verification failed for sanitized payload: %s', sanitize_for_log(payload[:100]))
        raise HTTPException(status_code=401, detail='Invalid signature')
    # Safe logging: sanitize user input and avoid logging raw signature
    safe_payload = sanitize_for_log(payload)
    logger.info('Action processed for payload: %s', safe_payload)
    return {'status': 'ok'}

Third, if you log structured events, use key-value formats that are less susceptible to injection, and ensure newline characters are escaped or replaced:

import json
def safe_log_event(event_type: str, details: dict):
    sanitized = {k: sanitize_for_log(str(v)) for k, v in details.items()}
    logger.info(json.dumps({'event': event_type, 'details': sanitized}))

# Usage
safe_log_event('action', {'user': payload.get('user'), 'resource': payload.get('resource')})

These practices ensure that HMAC-based authentication does not inadvertently amplify log injection risks. By sanitizing inputs before they reach log statements and avoiding verbose logging of raw signatures, you maintain both integrity verification and clean, reliable audit trails.

Frequently Asked Questions

Can HMAC signatures prevent log injection if the payload is trusted?
No. HMAC signatures verify integrity and authenticity but do not sanitize data. If you log fields from a verified payload without sanitization, log injection can still occur. Always sanitize data before writing to logs, regardless of signature validity.
Should I log failed HMAC verification details for troubleshooting?
Avoid logging raw payloads or detailed error context that could aid attackers. Log that verification failed and include only sanitized, minimal metadata. This reduces the risk of leaking information through log injection while still supporting auditability.