Cors Wildcard in Fastapi with Basic Auth
Cors Wildcard in Fastapi with Basic Auth — how this specific combination creates or exposes the vulnerability
In FastAPI, configuring CORS with a wildcard origin (origins=["*"]) while using HTTP Basic Authentication can unintentionally expose authenticated endpoints to any web page. With Basic Auth, credentials (username and password) are sent in the Authorization header as Basic base64(username:password). Browsers enforce same-origin policies and CORS checks for cross-origin requests. When allow_origins=["*"] is set together with allow_credentials=True, browsers block the frontend from reading the response, but the server may still process the request and return sensitive data. This creates a risk where a malicious site can make authenticated requests on behalf of a user if the user has an active session (e.g., a persistent token stored in localStorage and sent on every request).
For example, a dashboard at https://app.example.com could include a script that calls https://api.example.com/account/profile. If the API responds with personal data, the browser discards the response due to CORS, but the request and its side effects (such as changing state or exposing internal IDs) may still occur. This is especially risky when combined with other checks like BOLA/IDOR: an attacker could iterate over user IDs if authorization is not properly enforced server-side.
middleBrick scans such configurations and flags the combination as a high-risk pattern, noting that wildcard origins with credentials can bypass intended isolation. When an OpenAPI spec includes CORS extensions or the runtime returns permissive headers, the scanner correlates this with authentication mechanisms to highlight exposures in the Inventory Management and Authentication checks.
Another concern is reflected authentication challenges. Basic Auth does not involve cookies, but if the frontend manages tokens separately and the API uses wildcard CORS with credentials, preflight requests (OPTIONS) may reveal allowed methods and headers. Attackers can use this information to craft cross-origin requests that appear valid. The scanner’s Data Exposure and Authentication checks identify mismatches between declared CORS policy and runtime behavior, ensuring that permissive settings are not silently allowing broader access.
Because FastAPI applications often serve both APIs and web UIs, developers must ensure that allow_origins is restricted to known frontend domains. If a spec is provided, middleBrick resolves all $ref components and compares declared CORS settings against actual authentication schemes, mapping findings to frameworks like OWASP API Top 10 and GDPR data exposure risks.
Basic Auth-Specific Remediation in Fastapi — concrete code fixes
To secure FastAPI endpoints using HTTP Basic Authentication, explicitly define allowed origins and avoid wildcard credentials. Use CORSMiddleware with a list of trusted origins and set allow_credentials=True only when necessary. Always validate the Origin header on the server side, even if CORS middleware discards invalid requests.
Secure CORS configuration example
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import HTTPBasic
app = FastAPI()
security = HTTPBasic()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://dashboard.example.com", "https://app.example.com"],
allow_credentials=True,
allow_methods=["GET", "POST"],
allow_headers=["Authorization", "Content-Type"],
)
@app.get("/account/profile")
def read_profile(auth: dict = security):
username = auth["username"]
password = auth["password"]
# Validate credentials against a secure store
if not valid_credentials(username, password):
raise HTTPException(status_code=401, detail="Invalid credentials")
return {"user": username, "data": "sensitive"}
In this example, allow_origins is a specific list, preventing arbitrary web pages from making authenticated requests. The Authorization header is allowed, ensuring Basic Auth works across origins. For production, rotate credentials frequently and enforce HTTPS to prevent eavesdropping on the base64-encoded credentials.
Strict per-endpoint control
If you need tighter control, override CORS on a per-route basis by manually setting headers and avoiding middleware for sensitive paths. Combine this with rate limiting and input validation to mitigate BOLA/IDOR and injection risks.
from fastapi import Response
from fastapi.responses import JSONResponse
@app.get("/admin/settings")
def admin_settings(response: Response):
response.headers["Access-Control-Allow-Origin"] = "https://admin.example.com"
response.headers["Access-Control-Allow-Credentials"] = "true"
# Ensure no wildcard is echoed back
return {"settings": "restricted"}
middleBrick’s CLI can be used to verify that your deployed endpoints do not return disallowed origins when authentication is required. Run middlebrick scan <url> to get a per-category breakdown, including Authentication and CORS-related findings. The GitHub Action can fail builds if a response contains Access-Control-Allow-Origin: * alongside authentication headers, integrating security checks into CI/CD pipelines.
Finally, document the allowed origins in your API spec and ensure that $ref-resolved definitions in OpenAPI 2.0/3.0/3.1 accurately reflect runtime behavior. This reduces discrepancies that scanners might flag under Property Authorization and Data Exposure checks.
Related CWEs: dataExposure
| CWE ID | Name | Severity |
|---|---|---|
| CWE-200 | Exposure of Sensitive Information | HIGH |
| CWE-209 | Error Information Disclosure | MEDIUM |
| CWE-213 | Exposure of Sensitive Information Due to Incompatible Policies | HIGH |
| CWE-215 | Insertion of Sensitive Information Into Debugging Code | MEDIUM |
| CWE-312 | Cleartext Storage of Sensitive Information | HIGH |
| CWE-359 | Exposure of Private Personal Information (PII) | HIGH |
| CWE-522 | Insufficiently Protected Credentials | CRITICAL |
| CWE-532 | Insertion of Sensitive Information into Log File | MEDIUM |
| CWE-538 | Insertion of Sensitive Information into Externally-Accessible File | HIGH |
| CWE-540 | Inclusion of Sensitive Information in Source Code | HIGH |
Frequently Asked Questions
Can I safely use allow_origins=["*"] if I don’t enable allow_credentials=True?
allow_origins=["*"] without allow_credentials=True is generally safer because browsers do not send credentials (like the Basic Auth header) to cross-origin requests when credentials are not allowed. However, it can still expose HTTP methods and headers via preflight requests and may allow unauthorized read attempts in some JavaScript contexts. For endpoints that require authentication, specify exact origins instead.