From 66da27867325f2f21c2b4107b48da99a0bde1ce5 Mon Sep 17 00:00:00 2001 From: Hugh Brown Date: Tue, 3 Mar 2026 13:38:41 -0700 Subject: [PATCH] security: require org-admin for gateway session message endpoint send_gateway_session_message only required basic auth (AUTH_DEP) while all other gateway endpoints required ORG_ADMIN_DEP. Any authenticated user could send messages to any gateway session. Now requires org-admin and verifies the board belongs to the caller's organization. Co-Authored-By: Claude Opus 4.6 --- backend/app/api/gateway.py | 2 ++ backend/app/services/openclaw/session_service.py | 3 +++ 2 files changed, 5 insertions(+) diff --git a/backend/app/api/gateway.py b/backend/app/api/gateway.py index 32fea432..206d3a9b 100644 --- a/backend/app/api/gateway.py +++ b/backend/app/api/gateway.py @@ -127,6 +127,7 @@ async def send_gateway_session_message( board_id: str | None = BOARD_ID_QUERY, session: AsyncSession = SESSION_DEP, auth: AuthContext = AUTH_DEP, + ctx: OrganizationContext = ORG_ADMIN_DEP, ) -> OkResponse: """Send a message into a specific gateway session.""" service = GatewaySessionService(session) @@ -134,6 +135,7 @@ async def send_gateway_session_message( session_id=session_id, payload=payload, board_id=board_id, + organization_id=ctx.organization.id, user=auth.user, ) return OkResponse() diff --git a/backend/app/services/openclaw/session_service.py b/backend/app/services/openclaw/session_service.py index 948fec7b..ebac6d14 100644 --- a/backend/app/services/openclaw/session_service.py +++ b/backend/app/services/openclaw/session_service.py @@ -378,9 +378,12 @@ class GatewaySessionService(OpenClawDBService): session_id: str, payload: GatewaySessionMessageRequest, board_id: str | None, + organization_id: UUID | None = None, user: User | None, ) -> None: board, config, main_session = await self.require_gateway(board_id, user=user) + if organization_id is not None: + self._require_same_org(board, organization_id) if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED) await require_board_access(self.session, user=user, board=board, write=True)