From 42b64d75dc0489a0b2c99e1ab5c7045484456401 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 18 Jul 2026 03:12:12 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20Fix=20excep?= =?UTF-8?q?tion=20handling=20in=20admin=20login=20route?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: shadowcoder8 <185462083+shadowcoder8@users.noreply.github.com> --- .jules/sentinel.md | 12 ++++++++++++ main.py | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 65407a8..25fea28 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -21,3 +21,15 @@ Hardcoded credentials pose a critical risk because they provide an easy entry po **Prevention:** 1. Never commit secrets, API keys, or passwords into the source code repository. Always read sensitive configuration using environment variables (e.g., `os.getenv`). 2. Implement secure comparisons utilizing functions designed to prevent timing attacks, like `secrets.compare_digest()`, and properly encode inputs to prevent TypeErrors on non-ASCII characters. + +## 2024-05-20 - Exception Handling Information Leak in Admin Login + +**Vulnerability:** +The `admin_login` route in `main.py` had a generic `except Exception as e:` block that caught all exceptions and returned the exception's string representation `str(e)` to the client inside a 401 Unauthorized response. If an unexpected internal error occurred (e.g. database failure, missing environment variables leading to a 500 error in `authenticate_admin`), the underlying error details or stack trace fragments could be exposed to potential attackers. + +**Learning:** +Generic exception handlers that echo the error message back to the client violate the "fail securely" principle and create an Information Exposure vulnerability. Additionally, catching `Exception` indiscriminately in FastAPI can swallow intended `HTTPException` raises (like a 500 from misconfigured credentials), incorrectly returning them as 401s with leaked details. + +**Prevention:** +1. Explicitly catch known HTTPExceptions and re-raise them, or handle them appropriately. +2. Catch general `Exception` separately as a fallback and return generic, non-descriptive error messages to the client (e.g., "Internal server error") while logging the actual `str(e)` server-side. diff --git a/main.py b/main.py index 977e1f2..4b08251 100644 --- a/main.py +++ b/main.py @@ -92,9 +92,12 @@ async def admin_login(login_request: models.LoginRequest, response: Response): sessions[session_id] = login_request.username # Map session ID to username response.set_cookie("session_id", session_id, httponly=True) return {"message": "Login successful"} + except HTTPException as e: + logging.error(f"Login failed for {login_request.username}: {str(e.detail)}") + raise e except Exception as e: logging.error(f"Login failed for {login_request.username}: {str(e)}") - raise HTTPException(status_code=401, detail=str(e)) # Unauthorized + raise HTTPException(status_code=500, detail="Internal server error") # Admin logout route @app.post("/admin/logout/")