Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `main.py` application had a generic exception handler (`except Exception as e`) in the `/admin/login/` route that would catch all errors and re-raise them as an `HTTPException(status_code=401, detail=str(e))`. This incorrectly exposed internal details (like missing config errors raised as 500 `HTTPException`s from the auth module) directly to the client as strings within a 401 response, leaking internal stack details or configuration state.

**Learning:**
When implementing exception handling in route definitions, generic catch-all handlers (`Exception`) should never reflect raw exception strings (`str(e)`) back to the client. This exposes potentially sensitive internal workings. Furthermore, explicitly throwing `HTTPException` in lower-level logic (like `auth.py`) is ineffective if a higher-level route blindly catches it as a generic `Exception` and changes the status code.

**Prevention:**
1. Explicitly catch framework exceptions (like FastAPI's `HTTPException`) and re-raise them to preserve their intended status code and message.
2. Ensure generic `Exception` handlers return a sanitized, generic error message (e.g., "An unexpected error occurred") without exposing internal exception strings.
7 changes: 5 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 he:
logging.error(f"Login failed for {login_request.username}: {str(he)}")
raise he
except Exception as e:
logging.error(f"Login failed for {login_request.username}: {str(e)}")
raise HTTPException(status_code=401, detail=str(e)) # Unauthorized
logging.error(f"Unexpected login error for {login_request.username}: {str(e)}")
raise HTTPException(status_code=500, detail="An unexpected error occurred")

# Admin logout route
@app.post("/admin/logout/")
Expand Down