From 677c7637283f9da991273953eb2f561d367b595b Mon Sep 17 00:00:00 2001 From: danielaloni Date: Sun, 15 May 2022 15:25:09 +0300 Subject: [PATCH 1/4] Upon 403 login attempt by unregistered user return Invalid Password --- synapse/handlers/auth.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 61607cf2bad7..212e5ca0c4b2 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -1204,7 +1204,7 @@ async def validate_login( await self._failed_login_attempts_ratelimiter.can_do_action( None, (medium, address) ) - raise LoginError(403, "", errcode=Codes.FORBIDDEN) + raise LoginError(403, "Invalid password", errcode=Codes.FORBIDDEN) identifier_dict = {"type": "m.id.user", "user": user_id} From f5b8a90a4c7c4f9631f8d7ed2b813525eac0798b Mon Sep 17 00:00:00 2001 From: danielaloni Date: Tue, 17 May 2022 11:45:27 +0300 Subject: [PATCH 2/4] Changelog for PR #12738. --- changelog.d/12738.misc | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/12738.misc diff --git a/changelog.d/12738.misc b/changelog.d/12738.misc new file mode 100644 index 000000000000..6460e57db787 --- /dev/null +++ b/changelog.d/12738.misc @@ -0,0 +1 @@ +Change error message when attempting to login to a non-existent account to match that returned when the account exists but the password is invalid. Contributed by Daniel Aloni. \ No newline at end of file From 2232b1de5c82e54552e60dba958054baea1e5b72 Mon Sep 17 00:00:00 2001 From: danielaloni Date: Tue, 7 Jun 2022 09:36:07 +0300 Subject: [PATCH 3/4] Constant Invalid username or password message + CL --- changelog.d/12738.misc | 2 +- synapse/handlers/auth.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/changelog.d/12738.misc b/changelog.d/12738.misc index 6460e57db787..825222347540 100644 --- a/changelog.d/12738.misc +++ b/changelog.d/12738.misc @@ -1 +1 @@ -Change error message when attempting to login to a non-existent account to match that returned when the account exists but the password is invalid. Contributed by Daniel Aloni. \ No newline at end of file +Report login failures due to unknown third party identifiers in the same way as failures due to invalid passwords. This prevents an attacker from using the error response to determine if the identifier exists. Contributed by Daniel Aloni. \ No newline at end of file diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 212e5ca0c4b2..70bd7bad440f 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -80,6 +80,7 @@ logger = logging.getLogger(__name__) +INVALID_USERNAME_OR_PASSWORD = "Invalid username or password" def convert_client_dict_legacy_fields_to_identifier( submission: JsonDict, @@ -1204,7 +1205,7 @@ async def validate_login( await self._failed_login_attempts_ratelimiter.can_do_action( None, (medium, address) ) - raise LoginError(403, "Invalid password", errcode=Codes.FORBIDDEN) + raise LoginError(403, msg=INVALID_USERNAME_OR_PASSWORD, errcode=Codes.FORBIDDEN) identifier_dict = {"type": "m.id.user", "user": user_id} @@ -1330,7 +1331,7 @@ async def _validate_userid_login( # We raise a 403 here, but note that if we're doing user-interactive # login, it turns all LoginErrors into a 401 anyway. - raise LoginError(403, "Invalid password", errcode=Codes.FORBIDDEN) + raise LoginError(403, msg=INVALID_USERNAME_OR_PASSWORD, errcode=Codes.FORBIDDEN) async def check_password_provider_3pid( self, medium: str, address: str, password: str From 3a9fa27b2a0981f385e4737add2cd3728d628b0a Mon Sep 17 00:00:00 2001 From: danielaloni Date: Tue, 7 Jun 2022 17:16:26 +0300 Subject: [PATCH 4/4] Lint modifications. --- synapse/handlers/auth.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py index 70bd7bad440f..510bdc0d1534 100644 --- a/synapse/handlers/auth.py +++ b/synapse/handlers/auth.py @@ -82,6 +82,7 @@ INVALID_USERNAME_OR_PASSWORD = "Invalid username or password" + def convert_client_dict_legacy_fields_to_identifier( submission: JsonDict, ) -> Dict[str, str]: @@ -1205,7 +1206,9 @@ async def validate_login( await self._failed_login_attempts_ratelimiter.can_do_action( None, (medium, address) ) - raise LoginError(403, msg=INVALID_USERNAME_OR_PASSWORD, errcode=Codes.FORBIDDEN) + raise LoginError( + 403, msg=INVALID_USERNAME_OR_PASSWORD, errcode=Codes.FORBIDDEN + ) identifier_dict = {"type": "m.id.user", "user": user_id}