Xpath Injection in Fastapi with Basic Auth
Xpath Injection in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
Xpath Injection occurs when user-controlled data is concatenated into an XPath expression without proper escaping or parameterization, leading to authentication bypass or data disclosure. In Fastapi, this risk can emerge when the API relies on XPath queries (for example against an XML document store or an internal XML configuration) and also enforces HTTP Basic Authentication for access control. The combination does not directly weaken XPath, but it changes the threat surface: authentication is handled at the HTTP layer, while authorization and data filtering are performed in XPath logic. If the endpoint extracts credentials or user claims from the Basic Auth header and uses them to build XPath expressions, an attacker who supplies malicious input can manipulate the resulting node selection.
Consider an endpoint that receives a username via Basic Auth and uses it to query an XML user store:
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
import some_xml_library
app = FastAPI()
security = HTTPBasic()
def get_user_xml(username: str):
# Unsafe: username directly interpolated into XPath
xpath_expr = f"//user[name='{username}']"
return xml_db.select(xpath_expr)
@app.get("/profile")
def profile(credentials: HTTPBasicCredentials = Depends(security)):
user = get_user_xml(credentials.username)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
return {"username": user.find("name").text, "role": user.find("role").text}An attacker can supply ' or //* [password] as the username, causing the XPath to become //user[name='' or //* [password]], potentially returning nodes outside the intended scope and exposing other users’ data. Even if the endpoint does not directly use usernames in XPath, injection can arise when query parameters or body payloads influence XPath construction, especially when the API exposes XML introspection or bulk import features. Because Basic Auth transmits credentials in base64 (easily decoded), there is no confidentiality protection; any injection flaw in the XPath logic can be combined with credential harvesting to escalate impact.
Xpath Injection maps to the OWASP API Top 10 category “Broken Object Level Authorization” and can lead to unauthorized data exposure or privilege escalation. In a black-box scan, middleBrick tests unauthenticated attack surfaces and flags such input validation and authorization issues; with authenticated scans it can correlate findings with Basic Auth usage to produce a clearer risk picture. The scanner checks whether user-supplied values reach XPath selectors and reports findings with severity and remediation guidance, helping teams understand how injection paths relate to authentication boundaries.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on preventing injection by avoiding string concatenation for XPath and by applying strict input validation. Use parameterized XPath APIs where possible, and treat usernames and any user-controlled data as opaque values rather than part of expression syntax.
1. Use a safe XPath parameterization API
Replace string interpolation with an API that supports bound variables or positional/name-based substitution. The exact API varies by library; the principle is the same: user data is never parsed as part of the expression language.
from fastapi import FastAPI, Depends, HTTPException
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
# Example using a hypothetical safe API:
# xml_db.select("//user[name=$name]", {"$name": username})
def get_user_xml_safe(username: str):
# Safe: username is passed as a parameter, not concatenated
return xml_db.select("//user[name=$name]", {"$name": username}) # library-specific placeholder syntax
@app.get("/profile")
def profile(credentials: HTTPBasicCredentials = Depends(security)):
user = get_user_xml_safe(credentials.username)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
return {"username": user.find("name").text, "role": user.find("role").text}2. Validate and normalize usernames
Reject usernames that contain characters unlikely in identifiers (e.g., quotes, angle brackets) and enforce length and pattern rules. This reduces the attack surface even when parameterization is used.
import re
from fastapi import FastAPI, Depends, HTTPException, Security
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI()
security = HTTPBasic()
USERNAME_PATTERN = re.compile(r"^[a-zA-Z0-9_.-]{3,64}$")
def validate_username(username: str) -> str:
if not USERNAME_PATTERN.match(username):
raise HTTPException(status_code=400, detail="Invalid username format")
return username
def get_user_xml_safe(username: str):
# Safe parameterized call as above
return xml_db.select("//user[name=$name]", {"$name": username})
@app.get("/profile")
def profile(
credentials: HTTPBasicCredentials = Depends(security),
username: str = Security(lambda c: validate_username(c.username))
):
user = get_user_xml_safe(username)
if not user:
raise HTTPException(status_code=401, detail="Invalid credentials")
return {"username": user.find("name").text, "role": user.find("role").text}3. Use alternative identity handling where feasible
Avoid embedding identifiers in XPath when possible. Use a mapping layer (e.g., a database keyed by normalized usernames) and keep XPath scope narrow (e.g., selecting by ID rather than by name). Combine this with FastAPI dependency injection to centralize authorization checks, and consider token-based auth for richer claims instead of relying solely on HTTP Basic.
middleBrick’s scans include input validation and BOLA/IDOR checks that can surface XPath Injection risks; with the Pro plan you can run continuous monitoring and CI/CD integration to fail builds if such findings are detected in staging environments. The scanner does not fix code, but its findings include remediation guidance to help you apply these patterns and verify the fixes.