fix: implement subnet-aware CORS middleware to replace insecure wildcard origins

This commit is contained in:
2026-04-21 17:58:14 +03:00
parent 0d7ccf834b
commit 6f1e7731d7
2 changed files with 41 additions and 11 deletions

5
VERSION.json Normal file
View File

@@ -0,0 +1,5 @@
{
"version": "1.13.1",
"lastUpdated": "2026-04-21",
"phase": "Phase 2 Complete - CORS Security Fix"
}

View File

@@ -121,17 +121,42 @@ def is_origin_allowed(origin: str) -> bool:
return False return False
# Add CORS middleware FIRST (before rate limiter) # Add CORS middleware FIRST (before rate limiter)
# Temporary: Allow all origins to debug LDAP login issue # Uses is_origin_allowed() to validate exact origins + subnet matching
# TODO: Fix subnet matching in ALLOWED_ORIGINS configuration from starlette.middleware.base import BaseHTTPMiddleware
# For now, using ["*"] to allow all origins during testing from starlette.requests import Request
log.warning("⚠️ [CORS] Using allow_origins=['*'] - INSECURE FOR PRODUCTION!") from starlette.responses import Response
app.add_middleware(
CORSMiddleware, class SubnetAwareCORSMiddleware(BaseHTTPMiddleware):
allow_origins=["*"], # Temporarily allow all origins for testing async def dispatch(self, request: Request, call_next) -> Response:
allow_credentials=True, origin = request.headers.get("origin")
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
allow_headers=["*"], # Check if origin is allowed
) if origin and is_origin_allowed(origin):
response = await call_next(request)
response.headers["Access-Control-Allow-Origin"] = origin
response.headers["Access-Control-Allow-Credentials"] = "true"
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, PATCH, DELETE, OPTIONS"
response.headers["Access-Control-Allow-Headers"] = "*"
return response
# Handle CORS preflight requests
if request.method == "OPTIONS":
if origin and is_origin_allowed(origin):
return Response(
status_code=200,
headers={
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Methods": "GET, POST, PUT, PATCH, DELETE, OPTIONS",
"Access-Control-Allow-Headers": "*",
}
)
return Response(status_code=403)
return await call_next(request)
app.add_middleware(SubnetAwareCORSMiddleware)
log.info("🔒 [CORS] Subnet-aware middleware enabled (exact origins + subnet matching)")
# [H-02] Rate limiting on API # [H-02] Rate limiting on API
limiter = Limiter(key_func=get_remote_address) limiter = Limiter(key_func=get_remote_address)