Skip to content
Merged
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
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2026-02-03 - Information Leakage in Exception Handling
**Vulnerability:** The application was catching all exceptions and returning their string representation (`str(e)`) directly to the client in the HTTP 500 response. This could expose sensitive internal details (stack traces, database info, file paths).
**Learning:** Developers often pass `str(e)` to `HTTPException` for convenience during debugging, but this practice frequently makes it into production code, leading to information leakage.
**Prevention:** In production, catch `Exception` and raise `HTTPException` with a generic message (e.g., "Internal Server Error"). Ensure full exception details are logged using `logger.exception()` for server-side debugging.
2 changes: 1 addition & 1 deletion src/regression_model_template/controller/kafka_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ async def predict(request: PredictionRequest) -> PredictionResponse: # Use glob
return prediction_result # Use the global class
except Exception as e:
logger.exception("Error processing HTTP prediction request:")
raise HTTPException(status_code=500, detail=str(e))
raise HTTPException(status_code=500, detail="Internal Server Error")


@app.get("/health", summary="Health Check", tags=["System"])
Expand Down
36 changes: 36 additions & 0 deletions tests/controller/test_kafka_app_security.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest
from unittest.mock import patch, MagicMock
from fastapi import HTTPException
from regression_model_template.controller.kafka_app import (
PredictionRequest,
predict,
)
import asyncio
import regression_model_template.controller.kafka_app as kafka_app


def test_predict_endpoint_exception_leak():
"""Test that the predict endpoint does NOT leak exception details."""

async def run_async_test():
# Initialize the global variable if it's missing, or patch it.
# Since it might not be initialized, patch with create=True might work,
# or we can manually set it.

with patch(
"regression_model_template.controller.kafka_app.fastapi_kafka_service", create=True
) as mock_fastapi_kafka_service:
# Simulate a sensitive internal error
sensitive_error_message = "Database connection failed at 192.168.1.100:5432"
mock_fastapi_kafka_service.prediction_callback.side_effect = Exception(sensitive_error_message)

# Expect an HTTPException
with pytest.raises(HTTPException) as excinfo:
await predict(PredictionRequest())

# Verify that the sensitive message is leaked in the detail
assert excinfo.value.status_code == 500
assert excinfo.value.detail == "Internal Server Error"
assert excinfo.value.detail != sensitive_error_message

asyncio.run(run_async_test())