Skip to content

Commit fa71bb1

Browse files
authored
Drop support for delegating email validation (matrix-org#13192)
* Drop support for delegating email validation Delegating email validation to an IS is insecure (since it allows the owner of the IS to do a password reset on your HS), and has long been deprecated. It will now cause a config error at startup. * Update unit test which checks for email verification Give it an `email` config instead of a threepid delegate * Remove unused method `requestEmailToken` * Simplify config handling for email verification Rather than an enum and a boolean, all we need here is a single bool, which says whether we are or are not doing email verification. * update docs * changelog * upgrade.md: fix typo * update version number this will be in 1.64, not 1.63 * update version number this one too
1 parent 3f17833 commit fa71bb1

File tree

13 files changed

+110
-253
lines changed

13 files changed

+110
-253
lines changed

CHANGES.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Synapse vNext
2+
=============
3+
4+
As of this release, Synapse no longer allows the tasks of verifying email address ownership, and password reset confirmation, to be delegated to an identity server. For more information, see the [upgrade notes](https://github.com/matrix-org/synapse/blob/release-v1.63/docs/upgrade.md#upgrading-to-v1630).
5+
16
Synapse 1.63.0rc1 (2022-07-12)
27
==============================
38

@@ -73,15 +78,13 @@ Internal Changes
7378
- More aggressively rotate push actions. ([\#13211](https://github.com/matrix-org/synapse/issues/13211))
7479
- Add `max_line_length` setting for Python files to the `.editorconfig`. Contributed by @sumnerevans @ Beeper. ([\#13228](https://github.com/matrix-org/synapse/issues/13228))
7580

76-
7781
Synapse 1.62.0 (2022-07-05)
7882
===========================
7983

8084
No significant changes since 1.62.0rc3.
8185

8286
Authors of spam-checker plugins should consult the [upgrade notes](https://github.com/matrix-org/synapse/blob/release-v1.62/docs/upgrade.md#upgrading-to-v1620) to learn about the enriched signatures for spam checker callbacks, which are supported with this release of Synapse.
8387

84-
8588
Synapse 1.62.0rc3 (2022-07-04)
8689
==============================
8790

changelog.d/13192.removal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Drop support for delegating email verification to an external server.

docs/upgrade.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ process, for example:
8989
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
9090
```
9191
92+
# Upgrading to v1.64.0
93+
94+
## Delegation of email validation no longer supported
95+
96+
As of this version, Synapse no longer allows the tasks of verifying email address
97+
ownership, and password reset confirmation, to be delegated to an identity server.
98+
99+
To continue to allow users to add email addresses to their homeserver accounts,
100+
and perform password resets, make sure that Synapse is configured with a
101+
working email server in the `email` configuration section (including, at a
102+
minimum, a `notif_from` setting.)
103+
104+
Specifying an `email` setting under `account_threepid_delegates` will now cause
105+
an error at startup.
106+
92107
# Upgrading to v1.62.0
93108
94109
## New signatures for spam checker callbacks

docs/usage/configuration/config_documentation.md

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,30 +2168,26 @@ default_identity_server: https://matrix.org
21682168
---
21692169
### `account_threepid_delegates`
21702170

2171-
Handle threepid (email/phone etc) registration and password resets through a set of
2172-
*trusted* identity servers. Note that this allows the configured identity server to
2173-
reset passwords for accounts!
2171+
Delegate verification of phone numbers to an identity server.
21742172

2175-
Be aware that if `email` is not set, and SMTP options have not been
2176-
configured in the email config block, registration and user password resets via
2177-
email will be globally disabled.
2173+
When a user wishes to add a phone number to their account, we need to verify that they
2174+
actually own that phone number, which requires sending them a text message (SMS).
2175+
Currently Synapse does not support sending those texts itself and instead delegates the
2176+
task to an identity server. The base URI for the identity server to be used is
2177+
specified by the `account_threepid_delegates.msisdn` option.
21782178

2179-
Additionally, if `msisdn` is not set, registration and password resets via msisdn
2180-
will be disabled regardless, and users will not be able to associate an msisdn
2181-
identifier to their account. This is due to Synapse currently not supporting
2182-
any method of sending SMS messages on its own.
2179+
If this is left unspecified, Synapse will not allow users to add phone numbers to
2180+
their account.
21832181

2184-
To enable using an identity server for operations regarding a particular third-party
2185-
identifier type, set the value to the URL of that identity server as shown in the
2186-
examples below.
2182+
(Servers handling the these requests must answer the `/requestToken` endpoints defined
2183+
by the Matrix Identity Service API
2184+
[specification](https://matrix.org/docs/spec/identity_service/latest).)
21872185

2188-
Servers handling the these requests must answer the `/requestToken` endpoints defined
2189-
by the Matrix Identity Service API [specification](https://matrix.org/docs/spec/identity_service/latest).
2186+
*Updated in Synapse 1.64.0*: No longer accepts an `email` option.
21902187

21912188
Example configuration:
21922189
```yaml
21932190
account_threepid_delegates:
2194-
email: https://example.com # Delegate email sending to example.com
21952191
msisdn: http://localhost:8090 # Delegate SMS sending to this local process
21962192
```
21972193
---

synapse/app/homeserver.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
register_start,
4545
)
4646
from synapse.config._base import ConfigError, format_config_error
47-
from synapse.config.emailconfig import ThreepidBehaviour
4847
from synapse.config.homeserver import HomeServerConfig
4948
from synapse.config.server import ListenerConfig
5049
from synapse.federation.transport.server import TransportLayerServer
@@ -202,7 +201,7 @@ def _configure_named_resource(
202201
}
203202
)
204203

205-
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
204+
if self.config.email.can_verify_email:
206205
from synapse.rest.synapse.client.password_reset import (
207206
PasswordResetSubmitTokenResource,
208207
)

synapse/config/emailconfig.py

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import email.utils
1919
import logging
2020
import os
21-
from enum import Enum
2221
from typing import Any
2322

2423
import attr
@@ -131,41 +130,22 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
131130

132131
self.email_enable_notifs = email_config.get("enable_notifs", False)
133132

134-
self.threepid_behaviour_email = (
135-
# Have Synapse handle the email sending if account_threepid_delegates.email
136-
# is not defined
137-
# msisdn is currently always remote while Synapse does not support any method of
138-
# sending SMS messages
139-
ThreepidBehaviour.REMOTE
140-
if self.root.registration.account_threepid_delegate_email
141-
else ThreepidBehaviour.LOCAL
142-
)
143-
144133
if config.get("trust_identity_server_for_password_resets"):
145134
raise ConfigError(
146135
'The config option "trust_identity_server_for_password_resets" '
147-
'has been replaced by "account_threepid_delegate". '
148-
"Please consult the configuration manual at docs/usage/configuration/config_documentation.md for "
149-
"details and update your config file."
136+
"is no longer supported. Please remove it from the config file."
150137
)
151138

152-
self.local_threepid_handling_disabled_due_to_email_config = False
153-
if (
154-
self.threepid_behaviour_email == ThreepidBehaviour.LOCAL
155-
and email_config == {}
156-
):
157-
# We cannot warn the user this has happened here
158-
# Instead do so when a user attempts to reset their password
159-
self.local_threepid_handling_disabled_due_to_email_config = True
160-
161-
self.threepid_behaviour_email = ThreepidBehaviour.OFF
139+
# If we have email config settings, assume that we can verify ownership of
140+
# email addresses.
141+
self.can_verify_email = email_config != {}
162142

163143
# Get lifetime of a validation token in milliseconds
164144
self.email_validation_token_lifetime = self.parse_duration(
165145
email_config.get("validation_token_lifetime", "1h")
166146
)
167147

168-
if self.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
148+
if self.can_verify_email:
169149
missing = []
170150
if not self.email_notif_from:
171151
missing.append("email.notif_from")
@@ -356,18 +336,3 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
356336
"Config option email.invite_client_location must be a http or https URL",
357337
path=("email", "invite_client_location"),
358338
)
359-
360-
361-
class ThreepidBehaviour(Enum):
362-
"""
363-
Enum to define the behaviour of Synapse with regards to when it contacts an identity
364-
server for 3pid registration and password resets
365-
366-
REMOTE = use an external server to send tokens
367-
LOCAL = send tokens ourselves
368-
OFF = disable registration via 3pid and password resets
369-
"""
370-
371-
REMOTE = "remote"
372-
LOCAL = "local"
373-
OFF = "off"

synapse/config/registration.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
from synapse.types import JsonDict, RoomAlias, UserID
2121
from synapse.util.stringutils import random_string_with_symbols, strtobool
2222

23+
NO_EMAIL_DELEGATE_ERROR = """\
24+
Delegation of email verification to an identity server is no longer supported. To
25+
continue to allow users to add email addresses to their accounts, and use them for
26+
password resets, configure Synapse with an SMTP server via the `email` setting, and
27+
remove `account_threepid_delegates.email`.
28+
"""
29+
2330

2431
class RegistrationConfig(Config):
2532
section = "registration"
@@ -51,7 +58,9 @@ def read_config(self, config: JsonDict, **kwargs: Any) -> None:
5158
self.bcrypt_rounds = config.get("bcrypt_rounds", 12)
5259

5360
account_threepid_delegates = config.get("account_threepid_delegates") or {}
54-
self.account_threepid_delegate_email = account_threepid_delegates.get("email")
61+
if "email" in account_threepid_delegates:
62+
raise ConfigError(NO_EMAIL_DELEGATE_ERROR)
63+
# self.account_threepid_delegate_email = account_threepid_delegates.get("email")
5564
self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
5665
self.default_identity_server = config.get("default_identity_server")
5766
self.allow_guest_access = config.get("allow_guest_access", False)

synapse/handlers/identity.py

Lines changed: 1 addition & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
SynapseError,
2727
)
2828
from synapse.api.ratelimiting import Ratelimiter
29-
from synapse.config.emailconfig import ThreepidBehaviour
3029
from synapse.http import RequestTimedOutError
3130
from synapse.http.client import SimpleHttpClient
3231
from synapse.http.site import SynapseRequest
@@ -434,48 +433,6 @@ async def send_threepid_validation(
434433

435434
return session_id
436435

437-
async def requestEmailToken(
438-
self,
439-
id_server: str,
440-
email: str,
441-
client_secret: str,
442-
send_attempt: int,
443-
next_link: Optional[str] = None,
444-
) -> JsonDict:
445-
"""
446-
Request an external server send an email on our behalf for the purposes of threepid
447-
validation.
448-
449-
Args:
450-
id_server: The identity server to proxy to
451-
email: The email to send the message to
452-
client_secret: The unique client_secret sends by the user
453-
send_attempt: Which attempt this is
454-
next_link: A link to redirect the user to once they submit the token
455-
456-
Returns:
457-
The json response body from the server
458-
"""
459-
params = {
460-
"email": email,
461-
"client_secret": client_secret,
462-
"send_attempt": send_attempt,
463-
}
464-
if next_link:
465-
params["next_link"] = next_link
466-
467-
try:
468-
data = await self.http_client.post_json_get_json(
469-
id_server + "/_matrix/identity/api/v1/validate/email/requestToken",
470-
params,
471-
)
472-
return data
473-
except HttpResponseException as e:
474-
logger.info("Proxied requestToken failed: %r", e)
475-
raise e.to_synapse_error()
476-
except RequestTimedOutError:
477-
raise SynapseError(500, "Timed out contacting identity server")
478-
479436
async def requestMsisdnToken(
480437
self,
481438
id_server: str,
@@ -549,18 +506,7 @@ async def validate_threepid_session(
549506
validation_session = None
550507

551508
# Try to validate as email
552-
if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
553-
# Remote emails will only be used if a valid identity server is provided.
554-
assert (
555-
self.hs.config.registration.account_threepid_delegate_email is not None
556-
)
557-
558-
# Ask our delegated email identity server
559-
validation_session = await self.threepid_from_creds(
560-
self.hs.config.registration.account_threepid_delegate_email,
561-
threepid_creds,
562-
)
563-
elif self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
509+
if self.hs.config.email.can_verify_email:
564510
# Get a validated session matching these details
565511
validation_session = await self.store.get_threepid_validation_session(
566512
"email", client_secret, sid=sid, validated=True

synapse/handlers/ui_auth/checkers.py

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
from synapse.api.constants import LoginType
2121
from synapse.api.errors import Codes, LoginError, SynapseError
22-
from synapse.config.emailconfig import ThreepidBehaviour
2322
from synapse.util import json_decoder
2423

2524
if TYPE_CHECKING:
@@ -153,7 +152,7 @@ async def _check_threepid(self, medium: str, authdict: dict) -> dict:
153152

154153
logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
155154

156-
# msisdns are currently always ThreepidBehaviour.REMOTE
155+
# msisdns are currently always verified via the IS
157156
if medium == "msisdn":
158157
if not self.hs.config.registration.account_threepid_delegate_msisdn:
159158
raise SynapseError(
@@ -164,18 +163,7 @@ async def _check_threepid(self, medium: str, authdict: dict) -> dict:
164163
threepid_creds,
165164
)
166165
elif medium == "email":
167-
if (
168-
self.hs.config.email.threepid_behaviour_email
169-
== ThreepidBehaviour.REMOTE
170-
):
171-
assert self.hs.config.registration.account_threepid_delegate_email
172-
threepid = await identity_handler.threepid_from_creds(
173-
self.hs.config.registration.account_threepid_delegate_email,
174-
threepid_creds,
175-
)
176-
elif (
177-
self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL
178-
):
166+
if self.hs.config.email.can_verify_email:
179167
threepid = None
180168
row = await self.store.get_threepid_validation_session(
181169
medium,
@@ -227,10 +215,7 @@ def __init__(self, hs: "HomeServer"):
227215
_BaseThreepidAuthChecker.__init__(self, hs)
228216

229217
def is_enabled(self) -> bool:
230-
return self.hs.config.email.threepid_behaviour_email in (
231-
ThreepidBehaviour.REMOTE,
232-
ThreepidBehaviour.LOCAL,
233-
)
218+
return self.hs.config.email.can_verify_email
234219

235220
async def check_auth(self, authdict: dict, clientip: str) -> Any:
236221
return await self._check_threepid("email", authdict)

0 commit comments

Comments
 (0)