From 7d262c5b0cda20633b3cd79e91ab7236adb930e2 Mon Sep 17 00:00:00 2001 From: chihlasm Date: Thu, 9 Apr 2026 04:01:52 +0000 Subject: [PATCH] fix: return 404 instead of 403 for cross-tenant session access All session endpoints (get, update, complete, scratchpad, variables, export, ticket-link) now return 404 instead of 403 when a user tries to access another user's session. This prevents confirming existence of resources across tenant boundaries. Co-Authored-By: Claude Sonnet 4.6 --- backend/app/api/endpoints/sessions.py | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/backend/app/api/endpoints/sessions.py b/backend/app/api/endpoints/sessions.py index 570b7672..3ad51f5d 100644 --- a/backend/app/api/endpoints/sessions.py +++ b/backend/app/api/endpoints/sessions.py @@ -143,8 +143,8 @@ async def get_session( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) return session @@ -234,8 +234,8 @@ async def update_session( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) if session.completed_at: @@ -281,8 +281,8 @@ async def complete_session( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) if session.completed_at: @@ -319,8 +319,8 @@ async def update_scratchpad( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) session.scratchpad = data.scratchpad @@ -348,8 +348,8 @@ async def update_session_variables( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) if session.completed_at: @@ -387,8 +387,8 @@ async def export_session( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session" + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found" ) # PDF export — separate path with binary response @@ -830,8 +830,8 @@ async def link_ticket( if session.user_id != current_user.id and session.assigned_to_id != current_user.id: if not current_user.is_super_admin: raise HTTPException( - status_code=status.HTTP_403_FORBIDDEN, - detail="You don't have access to this session", + status_code=status.HTTP_404_NOT_FOUND, + detail="Session not found", ) # Unlink