From a1ea49affd9f5a895ba3e3f6f4b223e225f16918 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 20:17:09 +0000 Subject: [PATCH 1/2] Fix information leakage in predict endpoint exception handling Catch exceptions and return a generic 'Internal Server Error' message to the client, while logging the full exception trace on the server. This prevents exposing internal implementation details or sensitive information in HTTP 500 responses. Added a reproduction/verification test case in `tests/controller/test_kafka_app_security.py`. Co-authored-by: lgcorzo <46710567+lgcorzo@users.noreply.github.com> --- .jules/sentinel.md | 4 +++ .../controller/kafka_app.py | 2 +- tests/controller/test_kafka_app_security.py | 33 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .jules/sentinel.md create mode 100644 tests/controller/test_kafka_app_security.py diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..f7fa645 --- /dev/null +++ b/.jules/sentinel.md @@ -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. diff --git a/src/regression_model_template/controller/kafka_app.py b/src/regression_model_template/controller/kafka_app.py index 0f17f58..0bcd83a 100644 --- a/src/regression_model_template/controller/kafka_app.py +++ b/src/regression_model_template/controller/kafka_app.py @@ -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"]) diff --git a/tests/controller/test_kafka_app_security.py b/tests/controller/test_kafka_app_security.py new file mode 100644 index 0000000..fe49fda --- /dev/null +++ b/tests/controller/test_kafka_app_security.py @@ -0,0 +1,33 @@ +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()) From 06f8ac369d915e4103c84b94446bfdb848a2a9f4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 3 Feb 2026 20:23:27 +0000 Subject: [PATCH 2/2] Fix information leakage in predict endpoint exception handling Catch exceptions and return a generic 'Internal Server Error' message to the client, while logging the full exception trace on the server. This prevents exposing internal implementation details or sensitive information in HTTP 500 responses. Added a reproduction/verification test case in `tests/controller/test_kafka_app_security.py`. Co-authored-by: lgcorzo <46710567+lgcorzo@users.noreply.github.com> --- tests/controller/test_kafka_app_security.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/controller/test_kafka_app_security.py b/tests/controller/test_kafka_app_security.py index fe49fda..93857a7 100644 --- a/tests/controller/test_kafka_app_security.py +++ b/tests/controller/test_kafka_app_security.py @@ -8,6 +8,7 @@ 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.""" @@ -16,7 +17,9 @@ async def run_async_test(): # 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: + 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)