Preventing SSRF in FastAPI

Introduction

Welcome back! In the previous lesson, we explored the concept of Server-Side Request Forgery (SSRF) vulnerabilities and how to detect them. Now, we'll focus on preventing SSRF in FastAPI applications. By the end of this lesson, you'll understand how to secure your FastAPI applications against SSRF attacks, ensuring a safer web environment. Let's dive in! 🌟

Understanding SSRF in FastAPI

FastAPI is a modern, fast web framework for building APIs with Python, known for its simplicity and automatic API documentation. However, this flexibility can sometimes lead to vulnerabilities if not handled properly. SSRF vulnerabilities in FastAPI often arise when user input is not validated, allowing attackers to manipulate server-side requests.

When a FastAPI application receives a request, it processes the input and may make further requests to external resources. If this input is not properly validated, an attacker can craft a request that tricks the server into making unintended requests, potentially accessing sensitive data or services.

The Vulnerable Code

Let's examine a piece of code that demonstrates how SSRF vulnerabilities can occur in a FastAPI application:

from fastapi import FastAPI
from pydantic import BaseModel
import httpx

app = FastAPI()

class URLRequest(BaseModel):
    url: str

@app.post("/fetch-url")
async def fetch_url(request: URLRequest):
    try:
        # Proceed with the request to the validated URL with safety controls
        timeout = httpx.Timeout(10.0, connect=5.0)  # 10s total, 5s connect timeout
        limits = httpx.Limits(max_keepalive_connections=5, max_connections=10)
        
        async with httpx.AsyncClient(
            timeout=timeout,
            limits=limits,
            follow_redirects=False  # Prevent redirect-based allowlist bypass
        ) as client:
            response = await client.get(request.url)
            
            # Check response size to prevent memory exhaustion
            if len(response.content) > 1024 * 1024:  # 1MB limit
                raise HTTPException(status_code=413, detail="Response too large")
                
            return {"data": response.text}
    except Exception as e:
        return {"error": "Failed to fetch URL"}

In this code, the application accepts a URL from the user and fetches data from it using httpx. However, there's no validation to ensure the URL is safe or trusted. This lack of validation can lead to SSRF vulnerabilities, as attackers can provide malicious URLs to exploit the server.

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