KamoCRM

WebRTC signaling, webinar management and Canva schedules stop trusting the caller's say-so

FixMediaService
Shipped
September 23, 2026 at 2:12 AM UTC
Author
Kamo
Commit
fbdc871

Three more of the same shape. - WebRTCSignalingController relayed **************** straight to **************** using only the payload's own sessionGuid, with nothing checked about the CONNECTED caller — **************** are exactly as client-controlled as the session guid itself. Every handler now refuses to relay unless the STOMP session's own memberId (stamped at CONNECT, never client-supplied) is a member of that session. The companion SUBSCRIBE-side gap in StompDestinationAuthz (/topic/webrtc/session/ and /topic/chat/session/ aren't guarded there) needs a change in WebSocketConfig.preSend, which this task explicitly reserved for a different agent fixing a logging finding in that file — left alone here to avoid the collision; flagging it for the coordinator. - **************** updateWebinarType, deleteWebinarType, addPresenter, updatePresenter, removePresenter, addReminder and removeReminder all checked MANAGE_SUPPORT in the caller's OWN org but never compared it to the id's actual owning org — a manager anywhere on the platform could edit, delete or restaff any other org's webinar catalogue by id. Added **************** reminderOwnerOrgId (same shape as the existing restrictionOwnerOrgId) and a denyIfNotOwn* check in the controller before every mutation. getScheduledWebinars(typeId) returned every attendee's name and email to any org eligible to book the type — which, for a parent-published type, can be several unrelated child orgs with nothing to do with each other; it now omits the roster (attendeeCount is all WebinarScheduleWizard.tsx ever rendered from it) rather than gating the endpoint itself, which would have broken that legitimate cross-org booking flow. cancelWebinar had no right check at all; now the assigned presenter or the booking org's own MANAGE_SUPPORT holder may cancel, nobody else. - **************** and CanvaRecipeController.save checked only that the caller was signed in to the org, matching neither's own Materials settings tab (MANAGE_MATERIALS, +MANAGE_SOCIAL_MEDIA once social targets are set). runAsMemberId was stored verbatim from the request body — any member id in any org — so a schedule could be made to run recurring Canva generation, and auto-post to the org's own social accounts, using a completely unrelated member's connected Canva token. Now validated against the caller's own organization, and CanvaScheduleSweep re-checks the same fact at run time in case a row predates the fix or a member later changes org. Tests: **************** WebinarCrossOrgOwnershipTest and **************** pin the new rules against the real controllers/services (MockMvc over a mocked service/AuthHelper, matching GamesEntitlementEndpointTest's own reasoning for why the gate itself must be real). Mutation verified: neutering the ownership check in updateWebinarType and the runAsMemberId org check each turned exactly the test built for it red. Full `mvn test` green before this commit.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing