Xss Cross Site Scripting in Fastapi with Basic Auth
Xss Cross Site Scripting in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
Cross-site scripting (XSS) in a FastAPI service that uses HTTP Basic Authentication can arise when user-controlled data is reflected into HTML, JavaScript, or CSS without proper encoding, and when authentication state is handled in a way that amplifies impact. Basic Authentication typically relies on the browser sending an Authorization header on every request to a protected path. If an endpoint reflects an attacker-controlled value—such as a query parameter, header, or cookie—into the response without escaping, an injected script can execute in the victim’s browser under the context of the authenticated user.
Consider a FastAPI endpoint that reads a username from a request header or query parameter and includes it in the HTML response without sanitization or escaping. An attacker who can persuade or trick a logged-in victim to visit a crafted URL can deliver a payload like <script>steal(document.cookie)</script>. Because the victim’s browser includes credentials automatically for that origin, the malicious script runs with the privileges of the authenticated session, enabling session hijacking or unauthorized actions. Even when FastAPI uses Basic Auth via dependencies that validate credentials, failure to encode output enables injection regardless of how authentication is verified.
Another scenario involves user-controlled data being stored and later rendered in admin dashboards or logs that are viewed while authenticated. If those views embed data in script blocks or event handlers without escaping, stored XSS can occur. The combination of Basic Auth and insufficient output encoding means attackers don’t need to bypass authentication; they simply need a vector to inject executable code that will run in the context of privileged sessions. This makes it especially important to treat all reflected and stored data as untrusted, apply context-aware escaping (HTML, JS, URL), and enforce tight Content Security Policy where appropriate.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on never trusting data that originates from the client and ensuring that authentication does not bypass safe output handling. Below are concrete, working FastAPI examples that combine HTTP Basic Auth with secure response practices.
from fastapi import FastAPI, Depends, HTTPException, Header
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from starlette.responses import HTMLResponse
from html import escape
app = FastAPI()
security = HTTPBasic()
def get_current_user(credentials: HTTPBasicCredentials = Depends(security)):
# Replace with secure credential verification
if credentials.username == 'admin' and credentials.password == 'secret':
return credentials.username
raise HTTPException(status_code=401, detail='Invalid credentials')
@app.get('/hello', response_class=HTMLResponse)
def hello(user: str = Header(None), current_user: str = Depends(get_current_user)):
safe_user = escape(user) if user else 'Guest'
return f'<html><body>Hello, {safe_user}</body></html>'
In this example, the endpoint uses HTTP Basic Auth via HTTPBasic and a dependency that validates credentials. The user-controlled user value from a header is passed through Python’s html.escape before being interpolated into an HTML response, neutralizing any injected script. The browser will display the literal string if the header contains something like <script>alert(1)</script> instead of executing it.
For JSON APIs that render HTML snippets or are consumed by client frameworks, apply escaping in the serialization layer or on the client, and avoid putting raw user input into script contexts. If you must embed data in JavaScript, use safe serialization patterns such as JSON serialization with appropriate Content-Type, and never concatenate strings to form executable code. Below is a complementary pattern that keeps authentication explicit while ensuring safe templating:
from fastapi import FastAPI, Depends
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from pydantic import BaseModel
from typing import Any
app = FastAPI()
security = HTTPBasic()
class Item(BaseModel):
name: str
description: str = ''
def verify(credentials: HTTPBasicCredentials = Depends(security)):
if credentials.username == 'alice' and credentials.password == 'strongpassword':
return True
raise HTTPException(status_code=401, detail='Unauthorized')
@app.post('/items')
def create_item(payload: Item, _: bool = Depends(verify)):
# Safe: structured data, no direct HTML interpolation
return {'id': 1, 'name': payload.name, 'description': payload.description}
These patterns demonstrate that Basic Auth protects the endpoint from unauthenticated access, but XSS prevention requires output encoding and disciplined handling of any data that reaches the response. Treat authentication and output hygiene as independent controls: one secures entry, the other neutralizes injected content regardless of how a request was authenticated.
Related CWEs: inputValidation
| CWE ID | Name | Severity |
|---|---|---|
| CWE-20 | Improper Input Validation | HIGH |
| CWE-22 | Path Traversal | HIGH |
| CWE-74 | Injection | CRITICAL |
| CWE-77 | Command Injection | CRITICAL |
| CWE-78 | OS Command Injection | CRITICAL |
| CWE-79 | Cross-site Scripting (XSS) | HIGH |
| CWE-89 | SQL Injection | CRITICAL |
| CWE-90 | LDAP Injection | HIGH |
| CWE-91 | XML Injection | HIGH |
| CWE-94 | Code Injection | CRITICAL |