Xpath Injection in Fastapi with Jwt Tokens
Xpath Injection in Fastapi with Jwt Tokens
XPath Injection occurs when user-controlled data is concatenated into an XPath expression without proper sanitization or parameterization, allowing an attacker to alter query logic. In a Fastapi application that relies on XML data processing and uses JWT tokens for authentication, the combination can expose the unauthenticated attack surface to logic manipulation. Consider a service that accepts an XML document and an XPath query derived from a JWT claim or header value. If the XPath is built by string interpolation—such as "//user[username='" + username + "']"—an attacker can supply crafted input like admin' or '1'='1 to change the predicate and bypass intended access controls. Because the scan tests unauthenticated endpoints, middleBrick can detect whether XPath construction paths that depend on JWT-derived values are reachable without prior authentication, potentially exposing data selection logic to tampering.
JWT tokens commonly carry user roles or identifiers in claims, and developers may use these values directly in XPath expressions to enforce tenant or user scoping. However, JWTs themselves are often passed in the Authorization header and may be accepted without validation on certain endpoints during early development or misconfiguration. If an endpoint parses the JWT, extracts a subject or role, and then builds an XPath expression using that extracted data, the resulting query can be influenced by an attacker who provides a malicious token or manipulates header values. Even if the token is verified, embedding claims into XPath without parameterization introduces injection risk. The 12 parallel security checks include Authentication and Input Validation assessments, which can surface scenarios where XPath construction depends on JWT-derived inputs and lacks strict schema or type constraints.
Real-world impact can include unauthorized data access or elevation of privilege within XML datasets. For example, an attacker might supply an XPath that always evaluates to true, returning sensitive records across users. Because middleBrick performs black-box scanning and references real attack patterns such as OWASP API Top 10 A03:2023 Injection, reports will highlight XPath Injection findings with severity and remediation guidance. The tool also cross-references OpenAPI/Swagger specs, including $ref resolutions, to map the data flow from JWT usage to XPath construction, ensuring findings are tied to observable request paths rather than internal implementation assumptions.
Jwt Tokens-Specific Remediation in Fastapi
To mitigate XPath Injection when JWT tokens are involved, avoid building XPath expressions through string concatenation. Use parameterized XPath APIs where available, and treat JWT claims as untrusted inputs. Below are concrete remediation steps and code examples for Fastapi.
- Validate and sanitize inputs: Ensure any data used in XPath is constrained to expected patterns and never directly interpolated.
- Use parameterized XPath functions: Prefer APIs that support variable binding instead of string-based query assembly.
- Limit JWT claim usage in query logic: Avoid using role or subject claims to dynamically construct XPath predicates; instead enforce access controls via explicit permissions checks.
Example of vulnerable code that concatenates a JWT claim into an XPath expression:
from fastapi import Depends, FastAPI, Header, HTTPException
import jwt
app = FastAPI()
SECRET_KEY = "your-secret"
def get_current_user(authorization: str = Header(...)):
token = authorization.split(" ")[1] if authorization.startswith("Bearer ") else None
if not token:
raise HTTPException(status_code=401, detail="Missing token")
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return payload
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
@app.get("/users")
def read_users(xpath_query: str, user: dict = Depends(get_current_user)):
username = user.get("username", "")
# Vulnerable: direct string interpolation
expression = f"//user[username='{username}']/{xpath_query}"
# Simulated XML processing (replace with real library)
result = simulate_xpath_lookup(expression)
return {"data": result}
Secure alternative using strict input handling and avoiding dynamic XPath construction from JWT claims:
from fastapi import Depends, FastAPI, Header, HTTPException
import re
import jwt
app = FastAPI()
SECRET_KEY = "your-secret"
def get_current_user(authorization: str = Header(...)):
token = authorization.split(" ")[1] if authorization.startswith("Bearer ") else None
if not token:
raise HTTPException(status_code=401, detail="Missing token")
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
return payload
except jwt.InvalidTokenError:
raise HTTPException(status_code=401, detail="Invalid token")
# Strict allowlist for permitted xpath_query values
ALLOWED_XPATH_SEGMENTS = {"email", "profile", "preferences"}
def safe_xpath_append(base: str, segment: str) -> str:
if segment not in ALLOWED_XPATH_SEGMENTS:
raise HTTPException(status_code=400, detail="Invalid query segment")
# Use a library that supports parameterization; this example assumes a safe builder
return f"{base}/{segment}"
@app.get("/users")
def read_users(xpath_segment: str, user: dict = Depends(get_current_user)):
# Do not use JWT claims in XPath; use explicit, validated segment
base = "//user"
path = safe_xpath_append(base, xpath_segment)
result = simulate_xpath_lookup(path)
return {"data": result}
Additionally, apply global security checks such as authentication and input validation as part of your CI/CD pipeline. The middleBrick CLI can be integrated into scripts to scan endpoints and verify that JWT-dependent XPath paths are not exposed without proper guards.