From 6cac78f800a308c2d7ccabf54d22a5382a43e00d Mon Sep 17 00:00:00 2001 From: AGI-Corporation <186229839+AGI-Corporation@users.noreply.github.com> Date: Wed, 15 Apr 2026 17:27:25 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20[MEDIUM]=20?= =?UTF-8?q?Fix=20Exception=20Details=20Leakage=20in=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace user-facing internal exception details in HTTP 500 error messages with a generic string. - Record the internal exceptions via the standard python `logging` package to allow for server side tracing without leakage into external error messaging. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ agents/mistral_agent/agent.py | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index f07ab16..d3b6d53 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -1,3 +1,8 @@ +## 2026-04-15 - Error handling detail leakage in FastAPI +**Vulnerability:** The exception details were being logged explicitly and passed to users via `raise HTTPException(status_code=500, detail=str(e))`. This led to internal structure and potentially sensitive operational data to be inadvertently exposed to users. +**Learning:** Returning generic responses and suppressing complex error descriptions are a common best practice in API applications. When dealing with exceptions that might include full stack traces, server path locations or DB details we must use the standard error logging to log those issues securely for internal diagnosis and only show generic user facing messages to consumers of the API endpoints to limit potential information extraction. +**Prevention:** Avoid writing explicit `detail=str(e)` lines in endpoints catching generic Exception occurrences. Send standard, generic `HTTPException(status_code=500, detail="An internal server error occurred")` instead and use `logging.error(f"Error: {e}")` to correctly register those errors on the backend. + ## 2025-05-15 - Security Headers Middleware Implementation **Vulnerability:** Lack of defense-in-depth headers (X-Frame-Options, CSP, HSTS, etc.) made the application susceptible to clickjacking, MIME-sniffing, and protocol downgrade attacks. **Learning:** FastAPI/Starlette does not include these headers by default. Implementing them via `BaseHTTPMiddleware` provides a central way to enforce browser-side security policies across all endpoints. The CSP was specifically tuned to allow `'unsafe-inline'` for script and style to support the FastAPI Swagger UI without breaking functionality. diff --git a/agents/mistral_agent/agent.py b/agents/mistral_agent/agent.py index e09878d..9ce250d 100644 --- a/agents/mistral_agent/agent.py +++ b/agents/mistral_agent/agent.py @@ -8,6 +8,7 @@ """ import json +import logging import os import uuid from datetime import UTC, datetime @@ -318,7 +319,8 @@ async def gap_analysis(req: GapAnalysisRequest, db: AsyncSession = Depends(get_d "model": MISTRAL_MODEL, } except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) + logging.error(f"Error in gap analysis: {e}") + raise HTTPException(status_code=500, detail="An internal server error occurred") @router.post("/code-review", summary="DevSecOps code security analysis with Codestral") @@ -333,7 +335,8 @@ async def code_review(req: CodeReviewRequest, db: AsyncSession = Depends(get_db) ) return {"analysis": result, "model": MISTRAL_CODE_MODEL} except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) + logging.error(f"Error in code review: {e}") + raise HTTPException(status_code=500, detail="An internal server error occurred") @router.post("/ask", summary="Ask a CMMC/ZT compliance question") @@ -343,4 +346,5 @@ async def ask_question(req: QuestionRequest): answer = await agent.answer_compliance_question(req.question, req.context) return {"question": req.question, "answer": answer, "model": MISTRAL_MODEL} except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) + logging.error(f"Error in ask question: {e}") + raise HTTPException(status_code=500, detail="An internal server error occurred")