Skip to content

SSE: POST /sse/subscribe does not check the caller may see what it subscribes to #525

Description

@vincent-psarga

The gap

POST /sse/subscribe (apps/api/src/app/sse/sse.controller.ts) takes an eventType and an arbitrary params array and passes both to sseService.subscribeUser without checking that the caller may see the thing params names. Any authenticated user who knows a space id can therefore subscribe to that space's channel, whatever organization it belongs to.

Two event types are affected today:

What leaks

Activity, not content. Both events are deliberately thin — SPACE_CONTENT_CHANGED carries { organizationId, spaceId } and nothing else, precisely because a subscriber is not checked against the space it names, and every subscriber learns what changed by refetching through endpoints that do check. So a subscriber to a space they do not belong to learns that something changed in it, and when — not what, and not enough to read any of it.

That is a low ceiling, which is why #518 shipped rather than widening into this. It is still a timing side channel across organization boundaries, and it should not be the reason the payload has to stay thin forever.

What would close it

A membership check in the subscribe endpoint, per event type, before the subscription is registered — space-scoped types resolve params[0] as a space and check the caller belongs to it; unknown event types are refused rather than allowed by default. Both event types above gain it at once, so CHANGE_PROPOSAL_UPDATE subscribers need checking against the same rule.

Raised by Greptile on #518 (P2, security), and called out in that PR's own reviewer notes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions