Stop one member reaching another's calendar integration, and stop the endpoints handing out the credential

FixEmailService
Shipped
September 5, 2026 at 7:25 AM UTC
Author
Kamo
Commit
5355b88

Two defects on the /settings/integrations/member endpoints, both live and both reachable by any signed-in member. The id was the only access control. Every /member/{id} endpoint took the integration id straight from the path and asked nothing else, so a member could update another member's row -- including overwriting the credentials on it -- delete it, test it, or publish a sync trigger for it. A UUID is not an authorization check: ids travel in logs, support threads and browser history, and the row being addressed holds a mailbox credential. isMembersOwn now gates all four, answering 404 rather than 403 so that addressing somebody else's row does not confirm it exists, and logging the attempt because a real one is either a broken client or somebody walking ids. An ORG-level row is owned by nobody and so is never a member's own, which matters because that is the row holding the whole organization's OAuth grant. And the member responses still returned the entity. cbc238a took credentialsJson out of the two ORG endpoints and left the four member ones returning it, which is the same encrypted blob in the same response bodies, browser caches and proxy logs -- just on the paths I had not looked at. All four go through the same view now, reporting only WHETHER a credential is on file. The screen that calls these is unreachable today (nothing imports PersonalProviderSection, and it asks for a GET /member/{id} that is not mapped), so neither defect was being exercised. That is not a reason to leave either one: the endpoints are mapped, session-authenticated and serving.

All changes

Like what you see shipping?

Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.

Start Free ForeverView Pricing