CVE-2023-43796 (published 2023-10-31T17:15Z)

Synapse is an open-source Matrix homeserver Prior to versions 1.95.1 and 1.96.0rc1, cached device information of remote users can be queried from Synapse. This can be used to enumerate the remote users known to a homeserver. System administrators are encouraged to upgrade to Synapse 1.95.1 or 1.96.0rc1 to receive a patch. As a workaround, the `federation_domain_whitelist` can be used to limit federation traffic with a homeserver.\n

CVSS v3 base score: 5.3, MEDIUM (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: NVD-CWE-noinfo
cwe_name: Insufficient Information
description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
extended_description: Insufficient Information

Fix information:
repo_url: https://github.com/matrix-org/synapse
commit_details: repo_url: https://github.com/matrix-org/synapse
author: Patrick Cloke
author_date: 2023-10-31 09:58:30-04:00
msg: Merge pull request from GHSA-mp92-3jfm-3575
repository: repo_url: https://github.com/matrix-org/synapse
repo_name: matrix-org/synapse
description: Synapse: Matrix homeserver written in Python/Twisted.
repo_language: Python
owner: matrix-org
file_changes: filename: federation_server.py
change_type: ModificationType.MODIFY
diff: @@ -84,7 +84,7 @@ from synapse.replication.http.federation import (
 from synapse.storage.databases.main.lock import Lock
 from synapse.storage.databases.main.roommember import extract_heroes_from_room_summary
 from synapse.storage.roommember import MemberSummary
-from synapse.types import JsonDict, StateMap, get_domain_from_id
+from synapse.types import JsonDict, StateMap, get_domain_from_id, UserID
 from synapse.util import unwrapFirstError
 from synapse.util.async_helpers import Linearizer, concurrently_execute, gather_results
 from synapse.util.caches.response_cache import ResponseCache
@@ -999,6 +999,12 @@ class FederationServer(FederationBase):
     async def on_claim_client_keys(
         self, query: List[Tuple[str, str, str, int]], always_include_fallback_keys: bool
     ) -> Dict[str, Any]:
+        if any(
+            not self.hs.is_mine(UserID.from_string(user_id))
+            for user_id, _, _, _ in query
+        ):
+            raise SynapseError(400, "User is not hosted on this homeserver")
+
         log_kv({"message": "Claiming one time keys.", "user, device pairs": query})
         results = await self._e2e_keys_handler.claim_local_one_time_keys(
             query, always_include_fallback_keys=always_include_fallback_keys

programming_language: Python
filename: device.py
change_type: ModificationType.MODIFY
diff: @@ -328,6 +328,9 @@ class DeviceWorkerHandler:
         return result
 
     async def on_federation_query_user_devices(self, user_id: str) -> JsonDict:
+        if not self.hs.is_mine(UserID.from_string(user_id)):
+            raise SynapseError(400, "User is not hosted on this homeserver")
+
         stream_id, devices = await self.store.get_e2e_device_keys_for_federation_query(
             user_id
         )

programming_language: Python
filename: e2e_keys.py
change_type: ModificationType.MODIFY
diff: @@ -542,6 +542,12 @@ class E2eKeysHandler:
         device_keys_query: Dict[str, Optional[List[str]]] = query_body.get(
             "device_keys", {}
         )
+        if any(
+            not self.is_mine(UserID.from_string(user_id))
+            for user_id in device_keys_query
+        ):
+            raise SynapseError(400, "User is not hosted on this homeserver")
+
         res = await self.query_local_devices(
             device_keys_query,
             include_displaynames=(

programming_language: Python