Clickjacking in Fastapi with Hmac Signatures
Clickjacking in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability
Clickjacking is a client-side UI redress attack where an attacker tricks a user into interacting with a hidden or disguised element inside an invisible or overlayed frame. In a Fastapi application that uses Hmac Signatures for request integrity, clickjacking can still occur because the signature does not protect the rendering context in the browser. Hmac Signatures typically validate that a request or a payload has not been tampered with, but they do not prevent the response from being embedded inside an <iframe> or <frame> on a malicious page.
Consider a Fastapi endpoint that returns a sensitive action form (e.g., a fund transfer or a settings change) and includes an Hmac Signature in a header or in a hidden form field to verify the request origin. If this endpoint is served without anti-clickjacking protections, an attacker can host a page that embeds the endpoint inside a transparent or opaque frame, overlaying interactive elements to capture user input or simulate clicks. The Hmac Signature may validate correctly if the attacker forwards the user’s session or request parameters, but the framing itself bypasses any integrity protection the signature provides because the browser renders the content in an isolated context.
In practice, a vulnerable Fastapi route might render a page with an Hmac-signed form and rely solely on the signature to ensure the request is intentional. However, browsers will display the framed content unless explicitly prevented. Attackers can use CSS and JavaScript to hide the frame, position UI elements under the user’s cursor, or simulate interactions. The signature does nothing to stop the browser from presenting the page inside a frame, which means the combination of Clickjacking and Hmac Signatures in Fastapi exposes a gap where integrity checks exist but UI isolation is missing.
Real-world attack patterns referenced from OWASP API Top 10 and common web exploits show that framing sensitive actions without frame-ancestor restrictions enables clickjacking even when cryptographic integrity is enforced. For example, an endpoint that returns an HTML response with an Hmac-signed form can be loaded by an attacker’s page using <iframe src="https://api.example.com/transfer"> and styled to cover the entire viewport with a transparent layer. The user believes they are interacting with the attacker’s page, while the browser executes the signed request inside the invisible frame.
Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on preventing the response from being framed and ensuring that Hmac Signatures are coupled with anti-clickjacking headers and secure rendering practices. Fastapi applications should set the Content-Security-Policy header with frame-ancestors to restrict who can embed the page, and use X-Frame-Options where appropriate. The Hmac Signature should continue to validate request integrity, but it must not be the sole defense against UI redressing.
Below are concrete code examples for a Fastapi app that uses Hmac Signatures and adds clickjacking protections.
from fastapi import Fastapi, Request, Response
from fastapi.responses import HTMLResponse
import hmac
import hashlib
import time
import os
app = Fastapi()
SECRET = os.environ.get("HMAC_SECRET", "change-this-secret")
def generate_hmac(data: str) -> str:
return hmac.new(SECRET.encode(), data.encode(), hashlib.sha256).hexdigest()
@app.get("/transfer")
async def transfer_form(request: Request, response: Response):
nonce = str(int(time.time()))
payload = f"user=alice&action=transfer&nonce={nonce}"
signature = generate_hmac(payload)
# Set CSP to disallow framing by external sites
response.headers["Content-Security-Policy"] = "frame-ancestors 'self';"
# Optional: X-Frame-Options for broader compatibility
response.headers["X-Frame-Options"] = "DENY"
html = f"""
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="/transfer/confirm">
<input type="hidden" name="user" value="alice">
<input type="hidden" name="action" value="transfer">
<input type="hidden" name="nonce" value="{nonce}">
<input type="hidden" name="signature" value="{signature}">
<button type="submit">Confirm Transfer</button>
</form>
</body>
</html>
"""
return HTMLResponse(content=html)
@app.post("/transfer/confirm")
async def confirm_transfer(request: Request, response: Response):
form = await request.form()
user = form.get("user")
action = form.get("action")
nonce = form.get("nonce")
received_signature = form.get("signature")
payload = f"user={user}&action={action}&nonce={nonce}"
expected_signature = generate_hmac(payload)
if not hmac.compare_digest(expected_signature, received_signature):
response.status_code = 403
return {"error": "invalid signature"}
# Process the transfer safely; response does not need framing
response.headers["Content-Security-Policy"] = "frame-ancestors 'self';"
response.headers["X-Frame-Options" ] = "DENY"
return {"status": "success"}
In this example, the Fastapi routes set Content-Security-Policy: frame-ancestors 'self' and X-Frame-Options: DENY to prevent clickjacking. The Hmac Signature is generated over the form payload and verified on submission, ensuring request integrity. Note that framing protections are independent of the signature; the signature ensures the payload has not been altered, while CSP and X-Frame-Options prevent the page from being embedded by attackers.
For SPAs or API-driven UIs where responses are consumed programmatically, ensure that sensitive endpoints are not served with HTML content types that can be framed, and that CORS and CSP are configured to limit origins. middleBrick scans can help identify missing framing protections and weak anti-clickjacking headers, providing prioritized findings and remediation guidance aligned with OWASP API Top 10 and common compliance frameworks.