Security Logging and Monitoring in FastAPI Applications

Introduction

Welcome to the final lesson in our Server-Side Request Forgery (SSRF) Prevention in FastAPI course! In this lesson, we'll explore security logging and monitoring in depth. Effective logging and monitoring are crucial components of a comprehensive security strategy, as they help you detect, investigate, and respond to security incidents promptly. Let's dive in and discover how to implement these practices in your FastAPI applications! 📊

The Role of Security Logging

Security logging is the practice of recording events related to security concerns within your application. Properly implemented logs serve multiple purposes:

  1. Detecting Security Incidents: Logs can reveal suspicious activities that may indicate ongoing attacks.
  2. Investigating Breaches: After a security incident, logs provide valuable data for forensic analysis.
  3. Compliance Requirements: Many regulatory frameworks require specific logging practices.
  4. System Auditing: Logs help track user activities and system changes over time.

Let's implement a comprehensive logging system using Python's built-in logging module:

from fastapi import FastAPI, Request
import logging
import time

app = FastAPI()

# Configure logging format and handlers
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.StreamHandler(),
        logging.FileHandler('logs/error.log', mode='a'),
        logging.FileHandler('logs/combined.log', mode='a')
    ]
)

logger = logging.getLogger('web-service')

# Set error log to only log errors
error_handler = logging.FileHandler('logs/error.log')
error_handler.setLevel(logging.ERROR)
logger.addHandler(error_handler)

# Logging middleware
@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()
    
    # Log the request
    logger.info(f"{request.client.host} - {request.method} {request.url.path}")
    
    response = await call_next(request)
    
    # Log response details
    process_time = time.time() - start_time
    logger.info(f"Status: {response.status_code} - Time: {process_time:.3f}s")
    
    return response

# Add custom security logging middleware
@app.middleware("http")
async def security_logging_middleware(request: Request, call_next):
    # Log potentially suspicious activities
    if request.method == "POST":
        try:
            body = await request.json()
            url = body.get('url')
            if url:
                logger.warning('URL parameter detected', extra={
                    'ip': request.client.host,
                    'url': url,
                    'method': request.method,
                    'path': request.url.path,
                    'user_agent': request.headers.get('user-agent', '')
                })
        except:
            pass
    
    response = await call_next(request)
    return response

# Example route
@app.get("/")
async def root():
    return {"message": "Hello, world!"}

if __name__ == "__main__":
    import uvicorn
    logger.info('Server running on port 3000')
    uvicorn.run(app, host="localhost", port=3000)

This code sets up a robust logging system using Python's logging module. It logs all HTTP requests and errors to both the console and files, making it easier to monitor and analyze application activities.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal