Skip to content

Input Sanitization and HTTP HeadersΒΆ

🎯 What You’ll LearnΒΆ

  • Why input sanitization is critical for preventing attacks like SQL injection and XSS
  • How FastAPI and Pydantic help validate and sanitize input automatically
  • How to configure secure HTTP headers to protect against common exploits
  • Best practices for combining validation and headers to harden your API

🧠 Step 1: Input Sanitization¢

πŸ” Why sanitize input?ΒΆ

User input is the most common attack vector. Without sanitization, attackers can inject malicious code into your API. Examples:

  • SQL Injection: "' OR 1=1 --" could trick a query into returning all rows.
  • Cross-Site Scripting (XSS): <script>alert('hacked')</script> could run in a browser if returned unsafely.

βœ… How FastAPI helpsΒΆ

FastAPI uses Pydantic models to validate and parse input. This means:

  • Types are enforced (int, str, bool)
  • Invalid data is rejected automatically
  • You can add constraints (length, regex, ranges)

πŸ“„ Example: Validating a signup form

from pydantic import BaseModel, EmailStr, constr

class UserCreate(BaseModel):
    username: constr(min_length=3, max_length=20, regex="^[a-zA-Z0-9_]+$")
    email: EmailStr
    password: constr(min_length=8)
  • username must be alphanumeric and between 3–20 characters
  • email must be a valid email format
  • password must be at least 8 characters

FastAPI rejects invalid input before it reaches your database.


🧠 Step 2: Escaping and Cleaning Input¢

Even with validation, sometimes you need to escape or clean input before storing or displaying it.

Example: Preventing XSS when rendering user content in HTML templates:

import html

def sanitize_text(text: str) -> str:
    return html.escape(text)

This converts <script> into &lt;script&gt;, preventing execution.


πŸ”’ Step 3: Secure HTTP HeadersΒΆ

πŸ” Why headers matter?ΒΆ

HTTP headers instruct browsers how to handle your API responses. Misconfigured headers can expose users to attacks.

βœ… Important Security HeadersΒΆ

  • Content-Security-Policy (CSP): Restricts what scripts/styles can run
  • X-Content-Type-Options: Prevents MIME type sniffing
  • Strict-Transport-Security (HSTS): Forces HTTPS connections
  • X-Frame-Options: Prevents clickjacking by disallowing embedding in iframes

πŸ“„ Example: Adding headers in FastAPI

from fastapi import FastAPI, Response

app = FastAPI()

@app.middleware("http")
async def add_security_headers(request, call_next):
    response: Response = await call_next(request)
    response.headers["X-Content-Type-Options"] = "nosniff"
    response.headers["X-Frame-Options"] = "DENY"
    response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
    response.headers["Content-Security-Policy"] = "default-src 'self'"
    return response

Refer to the following links for more details on security headers:

  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security
  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options

🧠 Step 4: Best Practices¢

  • Always validate input with Pydantic models
  • Escape user-generated content before rendering in HTML
  • Apply strict security headers globally with middleware
  • Combine with HTTPS and rate limiting for layered defense

πŸ§ͺ Practice ChallengeΒΆ

  1. Create a CommentCreate model that:
    • Requires text to be 1–200 characters
    • Rejects empty or overly long comments
  2. Add middleware to enforce:
    • X-Frame-Options: SAMEORIGIN
    • Content-Security-Policy: default-src 'self'
  3. Test by sending malicious input like <script>alert('xss')</script> and confirm it’s safely escaped.

🧠 Recap¢

You now know how to:

  • Sanitize and validate input to block SQL injection and XSS
  • Use Pydantic constraints for strong validation
  • Apply secure HTTP headers to harden your API responses

Together, these practices make your FastAPI app resilient against common web attacks.