-
Notifications
You must be signed in to change notification settings - Fork 400
MSC2290: Separate Endpoints for Threepid Binding #2290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 23 commits
fdea3e3
7096092
f5b10c6
5193c31
cb7c072
5b259bf
1fc1e3c
196f27e
7b656e9
f36ed9a
f06ba49
4bc005a
af24676
2a55310
c57250b
0b67f34
3eda9f7
1e69a7f
169174e
53519f9
e50bb3d
87d641c
bd64ffc
40420d9
9311e89
219ebff
1a51a24
0332d53
ec7e795
46e7137
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
# Separate Endpoints for Binding Threepids | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
*Note: This MSC obseletes | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[MSC2229](https://github.com/matrix-org/matrix-doc/pull/2229), which dealt | ||
with changing the rules of the `bind` flag on [POST | ||
/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). | ||
That endpoint is being deprecated as part of this MSC, thus MSC2229 is no | ||
longer relevant.* | ||
|
||
On the Client Server API there is currently a single endpoint for binding a | ||
threepid (an email or a phone number): [POST | ||
/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid). | ||
Depending on whether the `bind` flag is `true` or `false`, the threepid will | ||
be bound to either a user's account on the homeserver, or both the homeserver | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
and an identity server. Note that we use the term `add` when talking about | ||
adding a threepid to a homeserver, and `bind` when binding a threepid to an | ||
identity server. This terminology will be used throughout the rest of this | ||
proposal. | ||
|
||
Typically, when using the `/account/3pid` endpoint, the identity server | ||
handles the verification -- either by sending an email to an email address, | ||
or a SMS message to a phone number. Once completed, the homeserver will check | ||
with the identity server that verification had indeed happened, and if so, | ||
the threepid would be either added to the homeserver, or added to the | ||
homeserver and bound to the identity server simultaneously. | ||
|
||
Now, consider the fact that the identity server used in this process is | ||
provided by the user, using the endpoint's `id_server` parameter. If the user were | ||
to supply a malicious identity server that would immediately answer "yes" to | ||
any threepid validation, then the user could add any threepid to their | ||
account on the homeserver (which is likely not something homeserver admins want). | ||
|
||
To be clear, this is not a long-standing security issue. It is not a problem | ||
in any released version of Synapse, as Synapse keeps a list of "trusted | ||
identity servers" that acts a whitelist for what identity servers a user can | ||
specify. | ||
|
||
The concept of this whitelist is being removed in this MSC however, as part | ||
of lessening the reliance of homeservers on identity servers. This cannot be | ||
done while the homeserver is still trusting an identity server for validation | ||
of threepids. If the endpoints are split, the homeserver will handle the | ||
validation of threepids being added to user accounts, and identity servers | ||
will validate threepids being bound to themselves. | ||
|
||
## Proposal | ||
|
||
To solve this problem, two new endpoints will be added to the Client Server | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Relatedly: my main question is how hitting /bind on the HS differs from hitting the IS directly. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The HS will just proxy this request. However, it will remember that the bind occurred, and when it comes time to unbind all of a user's threepids (during account deactivation or when they explicitly request it), then the homeserver is aware of what binds occurred where and can carry out the unbinds on the user's behalf. But other than that it is simply just proxying the request. |
||
API: `POST /account/3pid/bind` and `POST /account/3pid/add`. Both will | ||
require authentication and be rate-limited. The request parameters of `POST | ||
/account/3pid/bind` are the same as [POST | ||
/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid), | ||
minus the `bind` flag, and the contents of `three_pid_creds` have been | ||
brought to the top level of the request body. The request parameters of `POST | ||
/account/3pid/add` will simply consist of a JSON body containing | ||
`client_secret` and `sid`. | ||
|
||
The homeserver should prevent a threepid being added to a user's account if | ||
it already part of another user's account. However, the homeserver should not | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
check for existing threepids when binding to an identity server. Identity | ||
servers do not enforce this requirement and neither should the proxying | ||
homeserver. | ||
|
||
An example of binding a threepid to an identity server with this new endpoint | ||
is as follows: | ||
|
||
First the client must request the threepid be validated by its chosen identity server. | ||
|
||
``` | ||
POST https://identity.server/_matrix/identity/v2/validate/email/requestToken | ||
|
||
{ | ||
"client_secret": "don'tT3ll", | ||
"email": "[email protected]", | ||
"send_attempt": 1 | ||
} | ||
``` | ||
|
||
The identity server must send an email to the specified address, including a | ||
link to a URL on the identity server which will accept the validation session | ||
ID, the given client_secret, and a randomly-generated token. | ||
|
||
Once an email has been sent, the user clicks the link in the email, which | ||
notifies the identity server that the email has been verified. | ||
|
||
Next, the client completes the bind by calling the new endpoint on the homeserver: | ||
KitsuneRal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
POST https://home.server/_matrix/client/r0/account/3pid/bind | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
{ | ||
"id_server": "example.org", | ||
"id_access_token": "abc123_OpaqueString", | ||
"sid": "abc123987", | ||
"client_secret": "don'tT3ll" | ||
} | ||
``` | ||
|
||
The homeserver will then make a bind request to the specified identity server | ||
on behalf of the user. The homeserver will record if the bind was successful | ||
and notify the user. The homeserver will remember this bind and the identity | ||
server it occurred on so that it can perform an unbind later if the user | ||
requests it or their account is deactivated. | ||
|
||
The threepid has now been bound on the user's requested identity server | ||
without causing that threepid to be used for password resets or any other | ||
homeserver-related functions. | ||
|
||
For completeness, here is an example of adding a threepid to the homeserver | ||
only, using the `/account/3pid/add` endpoint: | ||
|
||
The homeserver is validating the threepid in this instance, so the client | ||
must use the `/requestToken` endpoint of the homeserver: | ||
|
||
``` | ||
POST https://home.server/_matrix/client/r0/account/3pid/email/requestToken | ||
|
||
{ | ||
"client_secret": "don'tT3ll", | ||
"email": "[email protected]", | ||
"send_attempt": 1, | ||
} | ||
``` | ||
|
||
Here the homeserver must send an email to the specified address, including a | ||
link to a URL on the homeserver which will accept the validation session ID, | ||
the given client_secret, and a randomly-generated token. | ||
|
||
Once an email has been sent, the user clicks the link in the email, which | ||
notifies the homeserver that the threepid has been verified. | ||
|
||
The client then sends a request to the endpoint on the homeserver to add | ||
the threepid to a user's account. | ||
|
||
``` | ||
POST https://home.server/_matrix/client/r0/account/3pid/add | ||
|
||
{ | ||
"sid": "abc123987", | ||
"client_secret": "don'tT3ll" | ||
} | ||
``` | ||
|
||
The homeserver checks the threepid validation session referred to by the | ||
given ID and client_secret was validated, and if so adds the threepid to the | ||
user's account. | ||
|
||
To achieve the above flows, some changes need to be made to existing | ||
endpoints. The [POST | ||
/account/3pid](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid) | ||
endpoint is deprecated as the two new endpoints replace its functionality. | ||
The `bind` parameter is to be removed, with the endpoint functioning as if | ||
`bind` was `false`. Allowing an endpoint to add a threepid to both the | ||
identity server and homeserver at the same time requires one to trust the | ||
other, which is the exact behaviour we're trying to eliminate. Doing this | ||
also helps backward compatibility, as explained in [Backwards | ||
compatibility](#backwards-compatibility). | ||
|
||
The `id_server` and `id_access_token` parameters are to be removed | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this obsoletes MSC2263 too then? :/ They were made optional in 2263 for the reason of maintaining backwards compatibility with clients. Removing them does not maintain that backwards compatibility. In fact, 2263 even introduces an error code to let the HS make the decision about whether or not it cares to give power to the homeserver without harming the protocol. This is duplicated effort. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can leave them as optional parameters but homeserver should ignore them else they are opening themselves up to malicious identity servers. And then at that point there's not much point in keeping them as optional parameters versus removing them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By removing them, it becomes impossible for I'd rather we keep the fields as optional and put a red box saying "you should abuse M_SERVER_NOT_TRUSTED at every given opportunity" until the deprecation period has passed and they get removed (as they are deprecated by MSC2263). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, iiuc the problem is:
I think, as long as the requests still work in synapse with an So I would suggest maybe keeping them optional for now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keeping them optional but returning There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2263 was specifically written to allow Synapse to not support There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't have homeservers throw But new servers can just ignore the parameter. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd still expect that servers throw the error instead of ignoring it, as ignoring it is against the spec. It'd be no different than a 500 error in the eyes of the client (which it should be handling because There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From a client perspective, we'd like old Riots to still be able add 3PIDs to the HS account. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jryans sounds like the server shouldn't be throwing the error then and instead handle the It would be intentional that adding 3PIDs be blocked - it's an error related to something the server is not comfortable with doing. This all should have come out on MSC2263, not here, as well. I'd still have the same opinion, but it's off-topic for this MSC (now). |
||
from all of the Client-Server API's `requestToken` endpoints. That is: | ||
|
||
* [POST /account/3pid/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-email-requesttoken) | ||
* [POST /account/3pid/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-3pid-msisdn-requesttoken) | ||
* [POST /register/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-register-email-requesttoken) | ||
* [POST /register/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-register-msisdn-requesttoken) | ||
* [POST /account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-email-requesttoken) | ||
* [POST /account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.5.0#post-matrix-client-r0-account-password-msisdn-requesttoken) | ||
|
||
Either the homeserver itself or a service that the homeserver delegates to | ||
should be handling the sending of validation messages, not a user-provided | ||
server. Any mention of the homeserver being able to proxy to an identity | ||
server in the above endpoint descriptions, as well as the text "It is | ||
imperative that the homeserver keep a list of trusted Identity Servers and | ||
only proxies to those that it trusts." is to be removed from all parts of the | ||
spec, as the homeserver should no longer need to trust any identity servers. | ||
turt2live marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Tradeoffs | ||
|
||
One may question why clients don't just contact an identity server directly | ||
to bind a threepid, bypassing the implications of binding through a | ||
homeserver. While this will work, binds should still occur through a | ||
homeserver such that the homeserver can keep track of which binds were made, | ||
which is important when a user wishes to deactivate their account (and remove | ||
all of their bindings made on different identity servers). | ||
|
||
A verification could occur on an identity server, which could then tell the | ||
homeserver that a validation happened, but then there are security | ||
considerations about how to authenticate an identity server in that instance | ||
(and prevent people pretending to be identity servers and telling homeservers | ||
about hundreds of fake threepid additions to a user's account). | ||
|
||
## Backwards compatibility | ||
anoadragon453 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
A new flag will be added to `/versions`' unstable_features section, | ||
`m.separate_add_and_bind`. If this flag is present and set to `true`, then | ||
clients should use the new API endpoints to carry out threepid adds and | ||
binds. If this flag is not present or set to `false`, clients should use | ||
`/account/3pid`, being aware that they can only bind threepids to the | ||
homeserver, not the identity server. | ||
|
||
Old matrix clients will continue to use the `/account/3pid` endpoint. This | ||
MSC removes the `bind` parameter and forces `/account/3pid` calls to act as | ||
if `bind` was set to `false`. Old clients will still be able to add 3pids to | ||
the homeserver, but not bind to the identity server. New homeservers must | ||
ignore any `id_server` information passed to this endpoint. | ||
|
||
## Security considerations | ||
|
||
Reducing the homeserver's trust in identity servers should be a boost to | ||
security and improve decentralisation in the Matrix ecosystem to boot. | ||
|
||
Some endpoints of the Client Server API allow a user to provide an | ||
`id_server` parameter. Caution should be taken for homeserver developers to | ||
stop using these user-provided identity servers for any sensitive tasks where | ||
possible, such as password reset or account registration, if it removes the | ||
concept of a trusted identity server list. |
Uh oh!
There was an error while loading. Please reload this page.