From d9a7043af970d1773ec4965c90422a998f362590 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sat, 5 Sep 2026 23:05:46 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=9B=A1=EF=B8=8F=20Sentinel:=20Fix=20sensi?= =?UTF-8?q?tive=20error=20details=20leakage=20in=20auth=20decorator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove `details: str(e)` from the unauthorized error response in `login_required` decorator to prevent leaking internal exception details or stack traces to unauthenticated callers. Add unit test coverage. Co-authored-by: Pmaster-dev <293764797+Pmaster-dev@users.noreply.github.com> --- .jules/sentinel.md | 1 + auth/utils.py | 5 +++-- src/handoff/__init__.py | 0 tests/test_auth.py | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 .jules/sentinel.md create mode 100644 src/handoff/__init__.py create mode 100644 tests/test_auth.py diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..2804c91 --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1 @@ +# Sentinel Journal - Security Learnings diff --git a/auth/utils.py b/auth/utils.py index 4bded89..d993e23 100644 --- a/auth/utils.py +++ b/auth/utils.py @@ -128,8 +128,9 @@ def decorated_function(*args, **kwargs): g.user_id = user_id g.user = user_data return f(*args, **kwargs) - except Exception as e: - return jsonify({'error': 'Unauthorized', 'details': str(e)}), 401 + except Exception: + # Secure error handling: do not expose exception details to caller + return jsonify({'error': 'Unauthorized'}), 401 return decorated_function diff --git a/src/handoff/__init__.py b/src/handoff/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_auth.py b/tests/test_auth.py new file mode 100644 index 0000000..11aa16d --- /dev/null +++ b/tests/test_auth.py @@ -0,0 +1,39 @@ +import sys +from unittest.mock import MagicMock, patch + +# Mock cache_db module dependencies required by auth.utils +mock_redis = MagicMock() +mock_models = MagicMock() +sys.modules['cache_db'] = MagicMock() +sys.modules['cache_db.redis_client'] = mock_redis +sys.modules['cache_db.models'] = mock_models + +from flask import Flask +from auth.utils import login_required, PasswordUtils, JWTUtils + + +def test_login_required_unauthorized_error_no_details_leak(): + """Verify login_required does not leak internal exception details in response.""" + app = Flask(__name__) + + @app.route('/protected') + @login_required + def protected_route(): + return {'status': 'ok'} + + with app.test_request_context('/protected'): + with patch('auth.utils.verify_jwt_in_request', side_effect=Exception('Secret internal stack trace detail')): + response, status_code = protected_route() + + assert status_code == 401 + json_data = response.get_json() + assert json_data == {'error': 'Unauthorized'} + assert 'details' not in json_data + + +def test_password_utils_hash_and_verify(): + """Verify password hashing and verification functionality.""" + pwd = "securepassword123" + hashed = PasswordUtils.hash_password(pwd) + assert PasswordUtils.verify_password(pwd, hashed) is True + assert PasswordUtils.verify_password("wrongpassword", hashed) is False