Skip to content

Latest commit

Β 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›‘οΈ FastAPI Security Headers

CI PyPI version Python versions License: MIT Dependencies Ko-fi

Downloads

The missing security headers middleware for FastAPI. Protect your API against XSS, clickjacking, MIME sniffing, and OWASP Top 10 web vulnerabilities with secure-by-default configurations and zero overhead.


⚑ Highlights

  • πŸš€ Zero Performance Overhead (Pure ASGI): Bypasses heavy Starlette wrappers. Injects headers directly into ASGI raw message streams without body buffering.
  • πŸ“¦ Zero Dependencies: Uses only Python's standard library (dataclasses, typing). Zero bloat in your dependency tree.
  • ⚑ Pre-compiled Bytes: Header tuples are encoded to (bytes, bytes) once at application startup, running in nanoseconds per request.
  • πŸŽ›οΈ Out-of-the-box Presets: Ready-made configurations for APIs, high-compliance environments, and mixed apps.
  • πŸ“– Swagger / ReDoc Friendly: Includes a dedicated preset that won't break your interactive /docs documentation.
  • πŸ”„ Route-Aware: Intelligently respects custom headers set by individual route handlers unless explicitly configured to override.
  • 🌐 WebSockets & Streaming Safe: Passes WebSockets and large streaming responses (StreamingResponse) seamlessly.

πŸ“¦ Installation

pip install fastapi-security-headers

πŸš€ Quickstart (30 Seconds)

Add the middleware to your FastAPI application in just 2 lines of code:

from fastapi import FastAPI
from fastapi_security_headers import SecurityHeadersMiddleware

app = FastAPI()

# Enable OWASP recommended security headers with secure defaults
app.add_middleware(SecurityHeadersMiddleware)

@app.get("/")
async def root():
    return {"message": "Protected by fastapi-security-headers"}

πŸ›‘οΈ The Security Headers Matrix

By default, fastapi-security-headers turns an F score on security scanners into an A+:

HTTP Header Default Value Attack Vector Mitigated
X-Content-Type-Options nosniff MIME-Sniffing: Prevents browsers from guessing content types, blocking malicious scripts disguised as images or JSON.
X-Frame-Options DENY Clickjacking: Prevents external sites from embedding your API inside hidden <iframe> overlays.
X-XSS-Protection 0 Audit Vulnerabilities: Disables legacy buggy XSS filters as recommended by OWASP.
Strict-Transport-Security max-age=31536000; includeSubDomains SSL Stripping / MitM: Enforces HTTPS for all future visits over the next 365 days.
Referrer-Policy strict-origin-when-cross-origin Data Leakage: Prevents leaking sensitive URL query parameters to third-party domains.
Permissions-Policy geolocation=(), microphone=(), camera=() Feature Abuse: Disables unused device APIs (GPS, camera, microphone).
Cross-Origin-Opener-Policy same-origin Side-Channel Attacks: Isolates browsing context against Spectre-style attacks.
Cross-Origin-Resource-Policy same-origin Cross-Origin Reads: Blocks external origins from reading your API responses.

πŸŽ›οΈ Built-in Presets

1. Presets.swagger_friendly() (Recommended for FastAPI)

Enforces strict Content Security Policy (CSP) while allowing necessary CDNs (cdn.jsdelivr.net) and assets for Swagger UI (/docs) and ReDoc (/redoc).

from fastapi import FastAPI
from fastapi_security_headers import SecurityHeadersMiddleware, Presets

app = FastAPI()
app.add_middleware(SecurityHeadersMiddleware, config=Presets.swagger_friendly())

2. Presets.api() (For Headless JSON APIs)

Hardened specifically for pure JSON microservices. Disallows all frames, scripts, and media loading:

app.add_middleware(SecurityHeadersMiddleware, config=Presets.api())

3. Presets.strict() (High-Compliance / Banking)

Maximum security posture for financial, health, and enterprise apps. Enforces 2-year HSTS with preload, require-corp, and strict CSP:

app.add_middleware(SecurityHeadersMiddleware, config=Presets.strict())

4. Presets.default()

Balanced baseline for general web applications.


πŸ”§ Custom Configuration

You can fully customize headers or disable any specific header by setting it to None:

from fastapi import FastAPI
from fastapi_security_headers import SecurityHeadersMiddleware, SecurityHeadersConfig, HSTSConfig

config = SecurityHeadersConfig(
    # Customize HSTS (e.g. disable on localhost or enable preload)
    strict_transport_security=HSTSConfig(max_age=63072000, include_subdomains=True, preload=True),
    # Allow iframes from the same origin
    x_frame_options="SAMEORIGIN",
    # Add custom enterprise security headers
    custom_headers={
        "X-Permitted-Cross-Domain-Policies": "none",
    }
)

app = FastAPI()
app.add_middleware(SecurityHeadersMiddleware, config=config)

Route-Level Overrides

By default (override=False), if a specific endpoint returns its own custom header, the middleware respects it and does not duplicate it:

from fastapi.responses import JSONResponse

@app.get("/embeddable-widget")
async def widget():
    # This endpoint specifically permits embedding
    return JSONResponse(
        content={"data": "widget"},
        headers={"x-frame-options": "SAMEORIGIN"}
    )

To force middleware headers across all endpoints regardless of route return values, set override=True:

app.add_middleware(SecurityHeadersMiddleware, override=True)

πŸ§ͺ Testing

Run the test suite locally with pytest:

pip install -e ".[dev]"
pytest -v

🀝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.


πŸ‘€ Author

Alejandro Tacoronte GonzΓ‘lez

If this project helps you secure your FastAPI applications, consider buying a coffee! β˜•

Ko-fi


πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

About

πŸ›‘οΈ The missing security headers middleware for FastAPI. Protect your API against XSS, clickjacking, MIME sniffing, and OWASP Top 10 web vulnerabilities with zero-config defaults

Topics

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages