HIGH xss cross site scriptingfastapihmac signatures

Xss Cross Site Scripting in Fastapi with Hmac Signatures

Xss Cross Site Scripting in Fastapi with Hmac Signatures — how this specific combination creates or exposes the vulnerability

Cross-site scripting (XSS) in a FastAPI application that uses HMAC signatures can still occur when signed data is rendered in the browser without proper output encoding. HMAC signatures verify integrity and authenticity of data (e.g., a JWT or a signed cookie), but they do not prevent the data itself from containing malicious script if the data was supplied by an attacker or includes unsafe user-controlled content. If a FastAPI endpoint reads a signed value from a request (such as a signed cookie or query parameter), trusts its content, and embeds it directly into an HTML response, an attacker can supply a payload that executes in victim browsers.

For example, an application may sign a user preference token with HMAC and later deserialize it server-side, then place a field from that payload into the HTML page. Because the signature validates only that the value was produced by the server (or by someone who knows the secret), the developer might assume the content is safe. However, if the payload includes something like <script>alert(1)</script> and the server embeds it unescaped into a script context or HTML context, reflected XSS occurs. OWASP API Top 10 and related standards classify this as injection into a browser context despite server-side integrity checks.

In a black-box scan, middleBrick tests such scenarios by observing whether data that originated from a signed source is reflected without appropriate escaping or sanitization. Even when HMAC protects the integrity of parameters, the unchecked reflection of attacker-influenced content remains a vulnerability. Developers must treat signed data as untrusted in terms of content and apply context-aware output encoding before inserting any dynamic value into HTML, JavaScript, or URL contexts.

  • Signed payloads are not automatically safe; validate and encode on output.
  • HMAC confirms integrity, not safety of the data content.
  • Reflected injection often occurs when templates or string concatenation embed signed fields without escaping.

Hmac Signatures-Specific Remediation in Fastapi — concrete code fixes

Remediation centers on strict validation of signed payloads and context-aware output encoding in templates or responses. Use a robust JWT or HMAC library, validate the signature strictly, and never directly inject potentially malicious fields into HTML. Below are concrete FastAPI examples.

HMAC verification with PyJWT (strict validation)

from fastapi import FastAPI, Request, HTTPException, Depends
from fastapi.responses import HTMLResponse
import jwt
from jwt.exceptions import InvalidSignatureError, DecodeError

app = FastAPI()
SECRET = b'your-strong-secret'
ALGORITHM = 'HS256'

def verify_signed_token(token: str) -> dict:
    try:
        payload = jwt.decode(token, SECRET, algorithms=[ALGORITHM])
        return payload
    except (InvalidSignatureError, DecodeError, jwt.PyJWTError) as e:
        raise HTTPException(status_code=401, detail="Invalid token")

@app.get("/profile")
def profile(token: str, response: HTMLResponse):
    data = verify_signed_token(token)
    username = data.get("username", "")
    # Safe: escape user-controlled data before embedding in HTML
    return {"user_display": escape(username)}

Safe HTML rendering with Jinja2 (AutoEscape enabled)

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates
from html import escape
import jwt

app = FastAPI()
templates = Jinja2Templates(directory="templates")
templates.env.autoescape = True

@app.get("/dashboard", response_class=HTMLResponse)
def dashboard(request: Request, token: str):
    try:
        payload = jwt.decode(token, SECRET, algorithms=[ALGORITHM])
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=401, detail="Invalid token")
    # Escape all dynamic values before sending to template
    safe_name = escape(payload.get("name", ""))
    return templates.TemplateResponse("dashboard.html", {"request": request, "name": safe_name})

HMAC utility for verifying incoming signed parameters

import hmac
import hashlib
from fastapi import HTTPException

def verify_hmac_param(param: str, received_signature: str, secret: bytes) -> bool:
    mac = hmac.new(secret, param.encode('utf-8'), hashlib.sha256)
    expected = mac.hexdigest()
    if not hmac.compare_digest(expected, received_signature):
        raise HTTPException(status_code=403, detail="Invalid signature")
    return True

# Usage in a route:
# verify_hmac_param(user_id, request.query_params["sig"], SECRET)

Additional practical notes:

  • Always set autoescape=True in Jinja2 (or equivalent) and use template auto-escaping; never mark content as safe unless you have validated and sanitized it.
  • Apply context-specific escaping: HTML text, HTML attribute, JavaScript string, and URL contexts each require different escaping strategies.
  • Validate input constraints (length, character set) even when the signature is valid.
  • Do not rely on HMAC alone to prevent XSS; combine signature verification with output encoding and a strong Content Security Policy where applicable.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Does a valid HMAC signature guarantee that the data is safe to embed in HTML?
No. HMAC ensures integrity and authenticity, not safety. An attacker can supply malicious content if the data source is compromised or untrusted; always encode and escape on output according to the context.
How does middleBrick detect XSS involving signed endpoints?
middleBrick tests whether data originating from signed sources is reflected without proper escaping or encoding in HTML, JavaScript, or URL contexts, and reports findings with remediation guidance.