Monitoring and Responding to SSRF Incidents

Introduction

Welcome to the third lesson of our Server-Side Request Forgery (SSRF) Prevention in FastAPI course! We've covered what SSRF is and how to prevent it in FastAPI applications. Now, let's focus on an equally important aspect: monitoring and responding to SSRF incidents. Even with robust prevention measures, it's essential to detect and respond to potential attacks quickly. Let's dive in! 🔍

The Importance of Monitoring

Monitoring is a critical component of a comprehensive security strategy. It allows you to:

  1. Detect potential SSRF attacks in real-time
  2. Collect data for forensic analysis
  3. Improve your security measures based on attack patterns
  4. Respond quickly to minimize damage

Let's explore how to set up effective monitoring for SSRF vulnerabilities in FastAPI applications.

Setting Up Request Logging

The first step in monitoring is to set up comprehensive request logging. This allows you to track and analyze all incoming requests, making it easier to detect suspicious activity:

from fastapi import FastAPI, Request
import logging
import time

app = FastAPI()

# Configure logging
logging.basicConfig(
    filename='access.log',
    level=logging.INFO,
    format='%(asctime)s - %(message)s'
)
logger = logging.getLogger(__name__)

@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

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

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="localhost", port=3000)

In this example, we use FastAPI middleware to log all HTTP requests to a file. The logging includes information such as the IP address, request method, URL, status code, and processing time.

Advanced SSRF Detection

To detect potential SSRF attacks, we need to implement more sophisticated monitoring. Let's create middleware that specifically looks for suspicious URL patterns:

from fastapi import FastAPI, Request
from urllib.parse import urlparse
import logging

app = FastAPI()

logger = logging.getLogger(__name__)

@app.middleware("http")
async def ssrf_detection_middleware(request: Request, call_next):
    # Extract URL from request body or query
    url = None
    if request.method == "POST":
        try:
            body = await request.json()
            url = body.get('url', '')
        except:
            pass
    else:
        url = request.query_params.get('url', '')
    
    if url and isinstance(url, str):
        try:
            parsed_url = urlparse(url)
            
            # Check for suspicious patterns
            suspicious_patterns = [
                '127.0.0.1',
                'localhost',
                'internal',
                '169.254.169.254',  # Cloud metadata service
                'file:',
                'dict:',
                'gopher:',
                '10.',
                '172.16.',
                '192.168.'
            ]
            
            is_suspicious = any(
                pattern in (parsed_url.hostname or '') or pattern in url
                for pattern in suspicious_patterns
            )
            
            if is_suspicious:
                # Log the suspicious request
                logger.warning(f"POTENTIAL SSRF ATTACK: {request.client.host} tried to access {url}")
                
                # Note: In production, you could integrate with an alerting service
                # For blocking operations, use a message queue or background task system
        except:
            # URL parsing failed, but we'll continue processing the request
            pass
    
    response = await call_next(request)
    return response

@app.post("/fetch-url")
async def fetch_url(request: Request):
    # Your secure URL fetching logic here
    return {"success": True}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="localhost", port=3000)

This middleware checks for suspicious URL patterns that might indicate an SSRF attack attempt. When detected, it logs the incident for further analysis. For production environments, you would typically integrate this with a message queue or background task system to trigger alerts without blocking the request processing.

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