Skip to content

Conversation

erikjohnston
Copy link
Member

@erikjohnston erikjohnston commented Aug 15, 2025

We should send events that rescind invites over federation.

Similarly, we should handle receiving such events. Unfortunately, the protocol doesn't make it possible to fully auth such events, and so we can only handle the case where the original inviter rescinded the invite (rather than a room admin).

Complement test: matrix-org/complement#797

We should send events that rescind invites over federation.

Similiarly, we should handle receiving such events. Unfortunately, the
protocol doesn't make it possible to fully auth such events, and so we
can only handle the case where the original inviter rescinded the invite
(rather than a room admin).
@erikjohnston erikjohnston force-pushed the erikj/revoke_invite_fed branch from ead3a78 to 885f7cc Compare August 15, 2025 10:09
Copy link
Contributor

@kegsay kegsay left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, very clear and well documented.

@erikjohnston erikjohnston marked this pull request as ready for review August 15, 2025 10:31
@erikjohnston erikjohnston requested a review from a team as a code owner August 15, 2025 10:31
Comment on lines +274 to +275
and membership_event_id
in pdu.auth_event_ids() # The invite should be in the auth events of the rescission.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we care about checking whether the invite event is in the auth events here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need it I guess, I was mirroring how we test if an event is an invite rescission on the send path.

There probably isn't a way for the server to receive a leave event for an invited user that isn't a rescission?

Copy link
Contributor

@MadLittleMods MadLittleMods Aug 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mirroring how we test if an event is an invite rescission on the send path.

Where is that?

This shotgun validation seems sketchy and flawed. Feels like some shenanigans can be had.

Since we're not in the room, we can't do auth checks since we don't have the state of the room (only the stripped state from the invite).

Perhaps we should be checking that the sender is at-least on the same server as the person who made the invite? We assume the server knows what it's doing.

Otherwise, feels like I can just craft a leave event from my evil server (not even in the room) that could trigger this. With the current check, this assumes you know the membership_event_id but that could be leaked like when I share one of the OpenTracing trace JSON files.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was mirroring how we test if an event is an invite rescission on the send path.

Where is that?

in the federation sender code here: https://github.com/element-hq/synapse/pull/18823/files#diff-4db75239ae91da3be91b6ccacb4dc969be778e832da2976b9b8fd628f16e6b52R655-R671

Perhaps we should be checking that the sender is at-least on the same server as the person who made the invite? We assume the server knows what it's doing.

We only accept recessions from the original invite sender, and the check is below. Before this point we check that the event is signed by the sender's domain, so other servers shouldn't be able to spoof it.

We should add a complement test for it though.

Comment on lines +648 to +649
# If we've rescinded an invite then we want to tell the
# other server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use PUT /_matrix/federation/v2/send_leave/{roomId}/{eventId} for this kind of thing?

I understand how PUT /_matrix/federation/v1/send/{txnId} should also probably work but any reason beyond convenient? Perhaps this might be a problem if homeservers ignore PDU's received here from rooms they're not participating in?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The /send_leave API is used in the other direction: where a HS not in the room wants to add an event that is in the room (e.g. when the invitee rejects an invite).

We could reuse it or add a /rescind_invite API that mirrors the /invite one, but I'm not sure there is much benefit to doing so. The reason we need a dedicated /invite is because the invitee server needs to sign the event before it gets added to the DAG

Comment on lines 257 to +258
if not is_in_room:
# Check if this is a leave event rescinding an invite
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to also be able to catch this scenario here but should we pass off to our normal handler of send_leave (on_send_membership_event)?

Currently, it says that it doesn't handle kicks but we could update it with the same rounded corner we're using here "We cannot fully auth the rescission event, but we can check if the sender of the leave event is the same as the invite."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense to also be able to catch this scenario here but should we pass off to our normal handler of send_leave (on_send_membership_event)?

I don't think so, as on_send_membership_event assumes the server is in thhe room, which is not the case here.

membership == Membership.INVITE
and membership_event_id
and membership_event_id
in pdu.auth_event_ids() # The invite should be in the auth events of the rescission.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if I get multiple invites from different servers? Who wins? Are all invites stored?

Can my server craft invites to a room I'm not even in? They wouldn't work to join but seems like they might appear

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

Successfully merging this pull request may close these issues.

3 participants