HIGH xss cross site scriptingfastapiapi keys

Xss Cross Site Scripting in Fastapi with Api Keys

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

Cross-site scripting (XSS) in FastAPI applications that rely on API keys for access control can still lead to reflected or stored injections when user-influenced data is rendered in responses without proper escaping. API keys typically identify the caller, but they do not enforce output context rules; authorization and input validation are separate concerns. If an endpoint accepts a parameter such as a search query or a user-supplied display name and embeds it directly into an HTML response without sanitization, an attacker can provide a payload like <script>steal(document.cookie)</script>. Even when a valid API key is presented, the server may return the payload as part of an HTML page, causing the victim’s browser to execute it in the context of your domain.

Consider a FastAPI endpoint that personalizes a page using an API key for rate limiting or analytics but also reflects the key or username in the HTML. If the endpoint does not treat data as untrusted, reflected XSS becomes feasible. For example, an attacker might send a crafted link containing both a stolen API key (via leakage) and a script payload. If the API key is logged or exposed in URLs or error messages, the attack surface expands. Similarly, stored XSS can occur when user-supplied content such as comments or profile fields is stored and later rendered in admin dashboards that use API keys for session handling. The presence of API keys does not mitigate missing output encoding; it can inadvertently aid social engineering by making requests appear authenticated.

SSRF and unsafe consumption patterns can indirectly support XSS by allowing attackers to influence endpoints that eventually render HTML. For instance, an SSRF-induced call to an internal service may return data that is concatenated into a response without escaping. In LLM-related flows, unchecked outputs that include user-controlled text may deliver script content if the application embeds LLM responses directly into web pages. middleBrick’s checks for Input Validation, Unsafe Consumption, and Data Exposure help surface these risks by correlating runtime behavior with spec definitions, including $ref resolution across OpenAPI 2.0, 3.0, and 3.1 documents.

Api Keys-Specific Remediation in Fastapi — concrete code fixes

Defend XSS in FastAPI by treating all external data as untrusted, enforcing strict content types, and applying context-aware escaping. API keys should be transmitted only over TLS, stored securely on the client (e.g., in HTTP-only cookies or secure storage), and never echoed into HTML, JavaScript, or URLs. Use FastAPI’s dependency injection to validate keys and keep authorization logic separate from response generation.

Below are concrete code examples for secure handling of API keys and user-supplied data in FastAPI.

from fastapi import FastAPI, Depends, Header, HTTPException, Request
from fastapi.responses import HTMLResponse, JSONResponse
from markupsafe import escape
import re

app = FastAPI()

# Secure API key validation via dependency
def verify_api_key(x_api_key: str = Header(None)):
    if not x_api_key or not re.match(r'^[A-Za-z0-9-_=]+\\.', x_api_key):
        raise HTTPException(status_code=401, detail="Invalid API key")
    # In practice, validate against a secure store; do not log or embed the raw key in responses
    return x_api_key

@app.get("/items", dependencies=[Depends(verify_api_key)], response_class=JSONResponse)
def list_items(query: str | None = None):
    # Always escape user input before any HTML context; use JSON responses where possible
    safe_query = escape(query) if query else None
    return {"results": safe_query}

@app.get("/profile/{username}", response_class=HTMLResponse)
def profile(username: str, api_key: str = Header(...)):
    # Validate key without exposing it
    verify_api_key(api_key)
    # Escape dynamic content inserted into HTML
    safe_username = escape(username)
    return f"

Profile

User: {safe_username}

" # For JSON responses, ensure Content-Type is application/json and do not serialize keys @app.get("/data") def get_data(token: str = Header(...)): verify_api_key(token) # Return data without echoing the token return {"status": "ok", "data": [1, 2, 3]}

Complementary measures include configuring CORS strictly, setting Secure and HttpOnly flags on cookies, and using Content-Security-Policy headers to limit script sources. When integrating with CI/CD, the middleBrick GitHub Action can add API security checks to your pipeline and fail builds if risk scores drop below your chosen threshold, helping catch regressions before deployment.

In dashboards and CLI workflows, the middleBrick CLI allows you to scan from the terminal with middlebrick scan <url>, while the Web Dashboard enables tracking scores over time. For AI-assisted development, the MCP Server lets you scan APIs directly from your coding assistant, supporting rapid feedback during implementation.

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 using API keys prevent XSS in FastAPI?
No. API keys identify and rate-limit callers but do not prevent cross-site scripting. XSS is prevented by input validation, output encoding, and context-aware escaping; never echo API keys or user data into HTML, JavaScript, or URLs without sanitization.
Can middleBrick detect XSS risks related to API key handling?
Yes. middleBrick runs checks such as Input Validation, Data Exposure, and Unsafe Consumption, and it correlates findings with OpenAPI/Swagger specs including full $ref resolution. This helps identify endpoints where user data may reach HTML responses without proper escaping, even when API keys are used for access control.