From 94d1675a97d843ff5c60cbf8cf2c39da4858847b Mon Sep 17 00:00:00 2001 From: aleksana Date: Mon, 22 Dec 2025 13:06:06 +0800 Subject: [PATCH] matrix-conduit: fix vulnerability in invite over federation --- ...t_fields_for_invites_over_federation.patch | 91 +++++++++++++++++++ pkgs/by-name/ma/matrix-conduit/package.nix | 5 + 2 files changed, 96 insertions(+) create mode 100644 pkgs/by-name/ma/matrix-conduit/fix_validate_event_fields_for_invites_over_federation.patch diff --git a/pkgs/by-name/ma/matrix-conduit/fix_validate_event_fields_for_invites_over_federation.patch b/pkgs/by-name/ma/matrix-conduit/fix_validate_event_fields_for_invites_over_federation.patch new file mode 100644 index 000000000000..c7641fb16fd3 --- /dev/null +++ b/pkgs/by-name/ma/matrix-conduit/fix_validate_event_fields_for_invites_over_federation.patch @@ -0,0 +1,91 @@ +From a0f57159572c81c8ae6f9c9440e5cd74315b8570 Mon Sep 17 00:00:00 2001 +From: Jason Volk +Date: Sun, 21 Dec 2025 22:04:07 +0000 +Subject: [PATCH] fix: validate event fields for invites over federation. + +--- + src/api/server_server.rs | 61 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/src/api/server_server.rs b/src/api/server_server.rs +index adc764ff..d29f6031 100644 +--- a/src/api/server_server.rs ++++ b/src/api/server_server.rs +@@ -2132,6 +2132,44 @@ pub async fn create_invite_route( + CanonicalJsonValue::String(event_id.to_string()), + ); + ++ let event_room_id: OwnedRoomId = serde_json::from_value( ++ signed_event ++ .get("room_id") ++ .ok_or(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "Event had no room_id field.", ++ ))? ++ .clone() ++ .into(), ++ ) ++ .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "room_id is not a room id."))?; ++ ++ if room_id != event_room_id { ++ return Err(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "room_id parameter does not match event.", ++ )); ++ } ++ ++ let event_type: StateEventType = serde_json::from_value( ++ signed_event ++ .get("type") ++ .ok_or(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "Event had no type field.", ++ ))? ++ .clone() ++ .into(), ++ ) ++ .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "type is not an event type."))?; ++ ++ if event_type != StateEventType::RoomMember { ++ return Err(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "Invite event was not m.room.member type.", ++ )); ++ } ++ + let sender: OwnedUserId = serde_json::from_value( + signed_event + .get("sender") +@@ -2144,6 +2182,29 @@ pub async fn create_invite_route( + ) + .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "sender is not a user id."))?; + ++ if sender.server_name() != sender_servername { ++ return Err(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "Invite sender must match the origin server.", ++ )); ++ } ++ ++ let event_content: RoomMemberEventContent = serde_json::from_value( ++ signed_event ++ .get("content") ++ .ok_or_else(|| Error::BadRequest(ErrorKind::InvalidParam, "Missing event content."))? ++ .clone() ++ .into(), ++ ) ++ .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid event content."))?; ++ ++ if event_content.membership != MembershipState::Invite { ++ return Err(Error::BadRequest( ++ ErrorKind::InvalidParam, ++ "Membership of invite event must be invite.", ++ )); ++ } ++ + let invited_user: Box<_> = serde_json::from_value( + signed_event + .get("state_key") +-- +GitLab + diff --git a/pkgs/by-name/ma/matrix-conduit/package.nix b/pkgs/by-name/ma/matrix-conduit/package.nix index 4bbd6dd8e167..5cc269af4c56 100644 --- a/pkgs/by-name/ma/matrix-conduit/package.nix +++ b/pkgs/by-name/ma/matrix-conduit/package.nix @@ -21,6 +21,11 @@ rustPlatform.buildRustPackage (finalAttrs: { hash = "sha256-rJyuR8Ie/JiNKNjQL21+Q1PWliEAm+lwGraGeDxEHyY="; }; + patches = [ + # https://gitlab.com/famedly/conduit/-/merge_requests/784 + ./fix_validate_event_fields_for_invites_over_federation.patch + ]; + cargoHash = "sha256-4ZA+3f8Kt+1JAm9KXnMRxAF+X9z8HSJoJe6Ny63SlnA="; # Conduit enables rusqlite's bundled feature by default, but we'd rather use our copy of SQLite.