|
|
|
@ -3,70 +3,76 @@
|
|
|
|
|
This MSC proposes removing the current requirement of the identity server to
|
|
|
|
|
send third-party request tokens, and allows homeservers to implement the
|
|
|
|
|
functionality instead. These request tokens are used to verify the identity of
|
|
|
|
|
the request auther as an owner of the third-party identity (3PID). This can be
|
|
|
|
|
used for binding a 3PID to an account, or for resetting passwords via email or
|
|
|
|
|
SMS. The latter is what this proposal mainly focuses on, but be aware that it
|
|
|
|
|
allows for any task that requires requesting a token through a 3PID to be
|
|
|
|
|
taken on by the homeserver instead of the identity server.
|
|
|
|
|
the request author as an owner of the third-party ID (3PID). This can be used
|
|
|
|
|
for binding a 3PID to an account, or for resetting passwords via email or SMS.
|
|
|
|
|
The latter is what this proposal mainly focuses on, but be aware that it allows
|
|
|
|
|
for any task that requires requesting a token for a 3PID to be taken on by the
|
|
|
|
|
homeserver instead of the identity server.
|
|
|
|
|
|
|
|
|
|
The intention is to put less trust in the identity server, which is currently
|
|
|
|
|
one of the most centralised components of Matrix. As it stands, an attacker in
|
|
|
|
|
control of a identity server can reset a user's password if the identity server
|
|
|
|
|
is considered trusted by that homeserver, and the user has registered at least
|
|
|
|
|
one 3PID. This is due to the identity server currently handling the job of
|
|
|
|
|
confirming the user's control of that identity.
|
|
|
|
|
one 3PID. This is due to the identity server handling the job of confirming the
|
|
|
|
|
user's control of that identity.
|
|
|
|
|
|
|
|
|
|
The MSC aims to simply clarify that homeservers can take on the responsibility
|
|
|
|
|
of sending password reset tokens themselves.
|
|
|
|
|
The MSC seeks to clarify that homeservers can take on the responsibility of
|
|
|
|
|
sending password reset tokens themselves, and a new response field that will
|
|
|
|
|
aid homeservers in doing so.
|
|
|
|
|
|
|
|
|
|
## Proposal
|
|
|
|
|
# Background
|
|
|
|
|
|
|
|
|
|
Currently when a client requests a password reset, it makes a call to either
|
|
|
|
|
Currently when a client requests a 3PID token, it makes a call to one of the
|
|
|
|
|
`/requestToken` endpoints on the homeserver. For instance, during password
|
|
|
|
|
resets, a token is requested from either
|
|
|
|
|
[/_matrix/client/r0/account/password/email/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-email-requesttoken)
|
|
|
|
|
or
|
|
|
|
|
[/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken).
|
|
|
|
|
This request is supplied all the necessary details as well as an `id_server`
|
|
|
|
|
field containing the address of a identity server trusted by the homeserver.
|
|
|
|
|
|
|
|
|
|
The `id_server` field is currently required as the homeserver must know where
|
|
|
|
|
to proxy the request to. This MSC proposes not to change the requirements of
|
|
|
|
|
this field. Instead, it asks to clarify that the homeserver is allowed to not
|
|
|
|
|
proxy the request, but carry it out itself. This would mean the homeserver can
|
|
|
|
|
both send password reset tokens (via email or SMS), as well as accept requests
|
|
|
|
|
an endpoint (with the same parameters as
|
|
|
|
|
[/_matrix/client/r0/account/password/msisdn/requestToken](https://matrix.org/docs/spec/client_server/r0.4.0.html#post-matrix-client-r0-account-password-msisdn-requesttoken),
|
|
|
|
|
depending on the medium of the 3PID. These requests are supplied all the
|
|
|
|
|
necessary details as well as an `id_server` field containing the domain address
|
|
|
|
|
of a identity server trusted by the homeserver.
|
|
|
|
|
|
|
|
|
|
In order to facilitate these requests, the homeserver will simply proxy them to
|
|
|
|
|
the identity server. The IS will send out a token via email or sms, the user
|
|
|
|
|
will click a link or enter the token into their client, and either the client
|
|
|
|
|
or the user's browser will make a request **directly to the identity server**
|
|
|
|
|
with the token for verification. The IS then informs the homeserver that
|
|
|
|
|
verification was successful. At this point you can likely see that there is
|
|
|
|
|
potential for abuse here, so instead Homeservers should be given the option to
|
|
|
|
|
stop proxying the request to the identity server, and instead just send and
|
|
|
|
|
validate the token themselves.
|
|
|
|
|
|
|
|
|
|
## Proposal
|
|
|
|
|
|
|
|
|
|
The homeserver should be allowed to either proxy `/requestToken` requests or
|
|
|
|
|
handle them itself. Specifically, this means that the homeserver can both send
|
|
|
|
|
password reset tokens (via email or SMS), as well as accept requests on an
|
|
|
|
|
arbitrary endpoint (with the same parameters as
|
|
|
|
|
[/_matrix/identity/api/v1/validate/email/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken))
|
|
|
|
|
to verify that token.
|
|
|
|
|
|
|
|
|
|
Consideration was taken not to make `id_server` and optional field. Let's
|
|
|
|
|
assume for a moment that it was optional. Now, a client could send a request to
|
|
|
|
|
`/requestToken` omitting the `id_server` field. The homeserver however has
|
|
|
|
|
opted to continue proxying `/requestToken` to the identity server, even though
|
|
|
|
|
it knows this is potentially insecure. The homeserver now has no idea which
|
|
|
|
|
identity server to proxy the request to, and must return a failure to the
|
|
|
|
|
client. The client could then make another request with an `id_server`, but
|
|
|
|
|
we've now made two requests that ended up in the same outcome, instead of one,
|
|
|
|
|
in hopes of saving a very small amount of bandwidth by omitting the field
|
|
|
|
|
originally.
|
|
|
|
|
|
|
|
|
|
An additional complication is that in the case of SMS, a full link to reset
|
|
|
|
|
passwords is not sent, but a short code. The client then asks the user to enter
|
|
|
|
|
this code, however the client may now not know where to send the code. Should
|
|
|
|
|
it send it to the identity server or the homeserver? Which sent out the code?
|
|
|
|
|
|
|
|
|
|
In order to combat this problem, the field `submit_url` should be added in the
|
|
|
|
|
response from both the email and msisdn variants of the `/requestToken`
|
|
|
|
|
Client-Server API, if and only if the verification message contains a code the
|
|
|
|
|
user is expected to enter into the client (for instance in the case of a short
|
|
|
|
|
code through SMS). It SHOULD be in the form of
|
|
|
|
|
`/_matrix/identity/api/v1/validate/{3pid_type}/submitToken`, similar to the
|
|
|
|
|
[same endpoint that exists in the Identity-Server
|
|
|
|
|
API](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken).
|
|
|
|
|
If this field is omitted, the client MUST continue the same behaviour from
|
|
|
|
|
before, which is to send the token to the identity server directly. This is
|
|
|
|
|
intended for backwards compatibility with older servers.
|
|
|
|
|
One additional complication that in the case of SMS, just a code is sent to a
|
|
|
|
|
person's phone. This is then given to the client, but the client may not know
|
|
|
|
|
where to send the code now, as it doesn't know whether the homeserver or
|
|
|
|
|
identity server generated it.
|
|
|
|
|
|
|
|
|
|
In order to combat this problem, the field `submit_url` MUST be added in the
|
|
|
|
|
response from all of the variants of `/requestToken` in the Client-Server API,
|
|
|
|
|
if and only if the verification message contains a code the user is expected to
|
|
|
|
|
enter into the client (for instance in the case of a short code through SMS).
|
|
|
|
|
This URL is simply where the client should submit this token. The endpoint
|
|
|
|
|
should accept the same parameters as
|
|
|
|
|
[/_matrix/identity/api/v1/validate/{3pid_type}/submitToken](https://matrix.org/docs/spec/identity_service/r0.1.0.html#post-matrix-identity-api-v1-validate-email-submittoken)
|
|
|
|
|
in the Identity Service API. The only recommendation to homeserver developers
|
|
|
|
|
for this endpoint's path is to not be exactly the same as that of the identity
|
|
|
|
|
server, in order to prevent clashes between setups running both an identity
|
|
|
|
|
server and homeserver on the same domain. If `submit_url` is omitted, the
|
|
|
|
|
client MUST continue the same behaviour from before, which is to send the token
|
|
|
|
|
to the identity server directly. This is intended for backwards compatibility
|
|
|
|
|
with older servers.
|
|
|
|
|
|
|
|
|
|
If the client receives a response to `/requestToken` with `submit_url`, it MUST
|
|
|
|
|
accept the token from user input, then make a POST request to the content of
|
|
|
|
|
accept a token from user input, then make a POST request to the content of
|
|
|
|
|
`submit_url` with the `sid`, `client_secret` and user-entered token.
|
|
|
|
|
`submit_url` can lead to anywhere the homeserver deems necessary for
|
|
|
|
|
verification. This data MUST be submitted as a JSON body.
|
|
|
|
@ -90,7 +96,7 @@ collect a token from the user and then submit it to the provided URL.
|
|
|
|
|
```
|
|
|
|
|
{
|
|
|
|
|
"sid": "123abc",
|
|
|
|
|
"submit_url": "https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken"
|
|
|
|
|
"submit_url": "https://homeserver.tld/_homeserver/password_reset/msisdn/submitToken"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
@ -99,7 +105,7 @@ user, say "123456", and then submit that as a POST request to the
|
|
|
|
|
`"submit_url"`.
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
POST https://homeserver.tld/_matrix/identity/api/v1/validate/msisdn/submitToken
|
|
|
|
|
POST https://homeserver.tld/_homeserver/password_reset/msisdn/submitToken
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
"sid": "123abc",
|
|
|
|
@ -120,15 +126,27 @@ If the client did not receive a `submit_url` field, they should instead assume
|
|
|
|
|
that verification will be completed out of band (e.g. the user clicks a link in
|
|
|
|
|
their email and makes the submitToken request with their web browser).
|
|
|
|
|
|
|
|
|
|
## Tradeoffs
|
|
|
|
|
## Dismissed Alternatives
|
|
|
|
|
|
|
|
|
|
If homeservers choose to not proxy the request, they will need to implement the
|
|
|
|
|
ability to send emails and/or SMS messages. This is left as a detail for the
|
|
|
|
|
homeserver implementation.
|
|
|
|
|
|
|
|
|
|
## Future Considerations
|
|
|
|
|
Consideration was taken not to make `id_server` an optional field. Let's
|
|
|
|
|
assume for a moment that it was optional. Now, a client could send a request to
|
|
|
|
|
`/requestToken` omitting the `id_server` field. The homeserver however has
|
|
|
|
|
opted to continue proxying `/requestToken` to the identity server, even though
|
|
|
|
|
it knows this is potentially insecure. The homeserver now has no idea which
|
|
|
|
|
identity server to proxy the request to, and must return a failure to the
|
|
|
|
|
client. The client could then make another request with an `id_server`, but
|
|
|
|
|
we've now made two requests that ended up in the same outcome, instead of one,
|
|
|
|
|
in hopes of saving a very small amount of bandwidth by omitting the field
|
|
|
|
|
originally.
|
|
|
|
|
|
|
|
|
|
At some point we should look into removing the `id_server` field altogether and
|
|
|
|
|
removing any email/SMS message sending from the identity server. This would
|
|
|
|
|
drastically reduce the amount of trust needed in the identity server and its
|
|
|
|
|
required ability. This is, however, a good first step.
|
|
|
|
|
|
|
|
|
|
## Tradeoffs
|
|
|
|
|
|
|
|
|
|
If homeservers choose to not proxy the request, they will need to implement the
|
|
|
|
|
ability to send emails and/or SMS messages. This is left as a detail for the
|
|
|
|
|
homeserver implementation.
|
|
|
|
|
|
|
|
|
|