Clickjacking in Fastapi
How Clickjacking Manifests in Fastapi
Clickjacking in Fastapi applications occurs when malicious actors embed your Fastapi endpoints inside invisible iframes, tricking authenticated users into unknowingly performing actions on your behalf. This attack vector exploits the trust that browsers place in user interactions and Fastapi's default behavior of serving content without clickjacking protections.
The most common Fastapi clickjacking scenario involves an attacker creating a malicious website that loads your Fastapi application's sensitive endpoints within an iframe styled with opacity: 0 or positioned off-screen. When victims visit the malicious site, they might click what appears to be a legitimate button, but actually triggers actions in your Fastapi app—like transferring funds, changing account settings, or deleting data.
Fastapi's vulnerability to clickjacking stems from its default middleware stack, which doesn't include X-Frame-Options headers or Content Security Policy directives. When Fastapi serves HTML responses (common in applications using Jinja2 templates or returning HTML directly), browsers have no instructions preventing these pages from being framed. This is particularly dangerous for Fastapi applications that expose state-changing endpoints like:
@app.post('/transfer')
async def transfer_funds(request: TransferRequest):
# Critical endpoint vulnerable to clickjacking
return await process_transfer(request)Another Fastapi-specific manifestation occurs with WebSocket endpoints. Attackers can create pages that establish WebSocket connections to your Fastapi application while users interact with seemingly unrelated content. Since Fastapi's WebSocket support doesn't inherently validate the origin of connections, an attacker could potentially hijack authenticated WebSocket sessions through clickjacking techniques.
Fastapi applications using OAuth2 or JWT authentication are especially vulnerable because the malicious iframe inherits the user's authenticated session. The attacker doesn't need to know credentials—they simply need the victim to be logged in and interact with the malicious page. This makes clickjacking attacks particularly effective against Fastapi admin dashboards, financial applications, or any interface with privileged operations.
Fastapi-Specific Detection
Detecting clickjacking vulnerabilities in Fastapi applications requires examining both the application code and runtime behavior. The most straightforward detection method involves scanning your Fastapi endpoints with middleBrick, which specifically tests for clickjacking vulnerabilities as part of its comprehensive API security assessment.
When middleBrick scans a Fastapi application, it checks for the presence of X-Frame-Options headers and evaluates Content Security Policy directives. The scanner attempts to load your endpoints within iframes from different origins to verify whether clickjacking protections are in place. For Fastapi applications specifically, middleBrick examines:
- Whether HTML responses include X-Frame-Options: DENY or SAMEORIGIN headers
- If Content-Security-Policy headers contain frame-ancestors directives
- Whether Fastapi's default middleware configuration exposes endpoints to framing
- Authentication state persistence across iframe boundaries
Manual detection in Fastapi involves reviewing your application's middleware stack and response headers. Check your Fastapi application for missing security headers by examining responses from sensitive endpoints:
curl -I https://your-fastapi-app.com/sensitive-endpoint
HTTP/2 200
content-type: application/json
server: uvicorn
date: Mon, 15 Jan 2024 10:00:00 GMTNotice the absence of X-Frame-Options or CSP headers in the response. Fastapi applications using CORS middleware are particularly vulnerable because CORS headers don't prevent clickjacking—they only control cross-origin resource sharing, not framing behavior.
Another detection technique involves testing your Fastapi application's response to frame-ancestors directives. Create a test page that attempts to embed your Fastapi endpoints and observe whether the browser blocks the framing attempt. Fastapi applications serving administrative interfaces or data modification endpoints should always fail this test if properly secured.
middleBrick's scanning process goes beyond simple header checks by actively attempting clickjacking attacks against your Fastapi endpoints. The scanner creates test scenarios where it tries to trigger actions through iframes, helping you understand the real-world exploitability of your Fastapi application's clickjacking vulnerabilities.
Fastapi-Specific Remediation
Securing Fastapi applications against clickjacking requires implementing proper HTTP security headers and understanding Fastapi's middleware architecture. The most effective approach combines multiple defensive layers to ensure comprehensive protection.
The primary remediation for Fastapi clickjacking is adding X-Frame-Options headers to all responses. Fastapi makes this straightforward through middleware configuration:
from fastapi import FastAPI
from fastapi.middleware import Middleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI(middleware=[
Middleware(HTTPSRedirectMiddleware),
@app.middleware('http')
async def clickjacking_protection(request, call_next):
response = await call_next(request)
response.headers['X-Frame-Options'] = 'DENY'
return responseThis middleware intercepts all Fastapi responses and adds the X-Frame-Options: DENY header, preventing any website from framing your Fastapi application. For applications that need to be framed by specific trusted domains, use 'SAMEORIGIN' instead.
Content Security Policy provides a more granular approach to clickjacking prevention in Fastapi. Add CSP headers through middleware:
@app.middleware('http')
async def csp_protection(request, call_next):
response = await call_next(request)
response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
return responseFastapi applications using Jinja2 templates should ensure CSP headers are sent with HTML responses. The CSP frame-ancestors directive is particularly effective because it's enforced by modern browsers and provides more control than X-Frame-Options.
For Fastapi applications with mixed content types, implement conditional clickjacking protection:
@app.middleware('http')
async def conditional_clickjacking_protection(request, call_next):
response = await call_next(request)
# Only add headers to HTML responses
if 'text/html' in response.headers.get('content-type', ''):
response.headers['X-Frame-Options'] = 'DENY'
response.headers['Content-Security-Policy'] = "frame-ancestors 'none'"
return responseFastapi applications using authentication should combine clickjacking protection with session security. Ensure that authenticated endpoints reject requests originating from untrusted origins, even if they pass through clickjacking attempts:
from starlette.requests import Request
from starlette.responses import JSONResponse
@app.middleware('http')
async def auth_clickjacking_protection(request: Request, call_next):
response = await call_next(request)
# Check if request came from iframe
if 'X-Frame-Options' not in response.headers:
origin = request.headers.get('origin')
if origin and not is_trusted_origin(origin):
return JSONResponse({'error': 'Unauthorized'}, status_code=403)
return responseThese Fastapi-specific implementations provide robust protection against clickjacking attacks while maintaining your application's functionality and user experience.