From da740bfbca85920d7ddf93d319f3780f02cc9044 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 5 Jun 2020 17:32:13 +0100 Subject: [PATCH] Clarifications to SSO login/UIA (#2608) including a bunch of text about security --- CONTRIBUTING.rst | 2 +- .../newsfragments/2608.clarification | 1 + specification/client_server_api.rst | 32 +- specification/modules/sso_login.rst | 328 +++++++++++++++--- 4 files changed, 291 insertions(+), 72 deletions(-) create mode 100644 changelogs/client_server/newsfragments/2608.clarification diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index fc5b146f..2d26e8a8 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -13,7 +13,7 @@ https://github.com/matrix-org/matrix-doc/blob/master/meta/documentation_style.rs Python code within the ``matrix-doc`` project should follow the same style as synapse, which is documented at -https://github.com/matrix-org/synapse/tree/master/docs/code_style.rst. +https://github.com/matrix-org/synapse/tree/master/docs/code_style.md. Matrix-doc workflows -------------------- diff --git a/changelogs/client_server/newsfragments/2608.clarification b/changelogs/client_server/newsfragments/2608.clarification new file mode 100644 index 00000000..da704fc5 --- /dev/null +++ b/changelogs/client_server/newsfragments/2608.clarification @@ -0,0 +1 @@ +Clarify the behaviour of SSO login and UI-Auth. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 574999be..27cbe8c5 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -1,4 +1,4 @@ -.. Copyright 2016 OpenMarket Ltd +.. Copyright 2016-2020 The Matrix.org Foundation C.I.C. .. .. Licensed under the Apache License, Version 2.0 (the "License"); .. you may not use this file except in compliance with the License. @@ -425,6 +425,8 @@ on the server-side and the user simply needs to provide their credentials again. In either case, the client's previously known access token will no longer function. +.. _`user-interactive authentication`: + User-Interactive Authentication API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -813,28 +815,8 @@ Single Sign-On provider. A client wanting to complete authentication using SSO should use the -`Fallback`_ authentication flow by opening a browser window for -``/_matrix/client/r0/auth/m.login.sso/fallback/web?session=<...>`` with the -session parameter set to the session ID provided by the server. - -The homeserver should return a page which asks for the user's confirmation -before proceeding. For example, the page could say words to the effect of: - - A client is trying to remove a device/add an email address/take over your - account. To confirm this action, re-authenticate with single sign-on. If you - did not expect this, your account may be compromised! - -Once the user has confirmed they should be redirected to the single sign-on -provider's login page. Once the provider has validated the user, the browser is -redirected back to the homeserver. - -The homeserver then validates the response from the single sign-on provider and -updates the user-interactive authentication session to mark the single sign-on -stage has been completed. The browser is shown the fallback authentication -completion page. - -Once the flow has completed, the client retries the request with the session -only, as above. +`Fallback`_ mechanism. See `SSO during User-Interactive Authentication`_ for +more information. Email-based (identity / homeserver) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @@ -940,6 +922,8 @@ should open is:: Where ``auth type`` is the type name of the stage it is attempting and ``session ID`` is the ID of the session given by the homeserver. +.. _`user-interactive authentication fallback completion`: + This MUST return an HTML page which can perform this authentication stage. This page must use the following JavaScript when the authentication has been completed: @@ -1157,7 +1141,7 @@ with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``. If the homeserver advertises ``m.login.sso`` as a viable flow, and the client supports it, the client should redirect the user to the ``/redirect`` endpoint -for `Single Sign-On <#sso-client-login>`_. After authentication is complete, the +for `client login via SSO`_. After authentication is complete, the client will need to submit a ``/login`` request matching ``m.login.token``. {{login_cs_http_api}} diff --git a/specification/modules/sso_login.rst b/specification/modules/sso_login.rst index 6dd4a332..986bed94 100644 --- a/specification/modules/sso_login.rst +++ b/specification/modules/sso_login.rst @@ -1,4 +1,4 @@ -.. Copyright 2019 New Vector Ltd +.. Copyright 2019-2020 The Matrix.org Foundation C.I.C. .. .. Licensed under the Apache License, Version 2.0 (the "License"); .. you may not use this file except in compliance with the License. @@ -12,34 +12,98 @@ .. See the License for the specific language governing permissions and .. limitations under the License. -SSO client login -================ +SSO client login/authentication +=============================== .. _module:sso_login: Single Sign-On (SSO) is a generic term which refers to protocols which allow users to log into applications via a single web-based authentication portal. -Examples include "Central Authentication Service" (CAS) and SAML. +Examples include OpenID Connect, "Central Authentication Service" (CAS) and SAML. -An overview of the process, as used in Matrix, is as follows: +This module allows a Matrix homeserver to delegate user authentication to an +external authentication server supporting one of these protocols. In this +process, there are three systems involved: -1. The Matrix client instructs the user's browser to navigate to the - |/login/sso/redirect|_ endpoint on the user's homeserver. + * A Matrix client, using the APIs defined this specification, which is seeking + to authenticate a user to a Matrix homeserver. + + * A Matrix homeserver, implementing the APIs defined in this specification, but + which is delegating user authentication to the authentication server. + + * An "authentication server", which is responsible for authenticating the + user. + +This specification is concerned only with communication between the Matrix +client and the homeserver, and is independent of the SSO protocol used to +communicate with the authentication server. Different Matrix homeserver +implementations might support different SSO protocols. + +Clients and homeservers implementing the SSO flow will need to consider both login_ +and `user-interactive authentication`_. The flow is +similar in both cases, but there are slight differences. + +Typically, SSO systems require a single "callback" URI to be configured at the +authentication server. Once the user is authenticated, their browser is +redirected to that URI. It is up to the Matrix homeserver implementation to +implement a suitable endpoint. For example, for CAS authentication the +homeserver should provide a means for the administrator to configure where the +CAS server is and the REST endpoints which consume the ticket. + +Client login via SSO +--------------------- + +An overview of the process is as follows: + +0. The Matrix client calls |GET /login|_ to find the supported login + types, and the homeserver includes a flow with ``"type": "m.login.sso"`` in the + response. + +1. To initiate the ``m.login.sso`` login type, the Matrix client instructs the + user's browser to navigate to the |/login/sso/redirect|_ endpoint on the + user's homeserver. 2. The homeserver responds with an HTTP redirect to the SSO user interface, which the browser follows. -3. The SSO system authenticates the user. +3. The authentication server and the homeserver interact to verify the user's + identity and other authentication information, potentially using a number of + redirects. -4. The SSO server and the homeserver interact to verify the user's identity - and other authentication information, potentially using a number of redirects. - -5. The browser is directed to the ``redirectUrl`` provided by the client with +4. The browser is directed to the ``redirectUrl`` provided by the client with a ``loginToken`` query parameter for the client to log in with. +5. The client exchanges the login token for an access token by calling the + |/login|_ endpoint with a ``type`` of ``m.login.token``. + +For native applications, typically steps 1 to 4 are carried out by opening an +embedded web view. + +These steps are illustrated as follows:: + + Matrix Client Matrix Homeserver Auth Server + | | | + |-------------(0) GET /login----------->| | + |<-------------login types--------------| | + | | | + | Webview | | + | | | | + |----->| | | + | |--(1) GET /login/sso/redirect-->| | + | |<---------(2) 302---------------| | + | | | | + | |<========(3) Authentication process================>| + | | | | + | |<--(4) redirect to redirectUrl--| | + |<-----| | | + | | | + |---(5) POST /login with login token--->| | + |<-------------access token-------------| | + + .. Note:: In the older `r0.4.0 version `_ - of this specification it was possible to authenticate via CAS when the server + of this specification it was possible to authenticate via CAS when the homeserver provides a ``m.login.cas`` login flow. This specification deprecates the use of ``m.login.cas`` to instead prefer ``m.login.sso``, which is the same process with the only change being which redirect endpoint to use: for ``m.login.cas``, use @@ -47,40 +111,65 @@ An overview of the process, as used in Matrix, is as follows: The endpoints are otherwise the same. Client behaviour ----------------- +~~~~~~~~~~~~~~~~ The client starts the process by instructing the browser to navigate to |/login/sso/redirect|_ with an appropriate ``redirectUrl``. Once authentication is successful, the browser will be redirected to that ``redirectUrl``. -.. TODO-spec +{{sso_login_redirect_cs_http_api}} - Should we recommend some sort of CSRF protection here (specifically, we - should guard against people accidentally logging in by sending them a link - to ``/login/sso/redirect``. +Security considerations ++++++++++++++++++++++++ - Maybe we should recommend that the ``redirectUrl`` should contain a CSRF - token which the client should then check before sending the login token to - ``/login``? +1. CSRF attacks via manipulation of parameters on the ``redirectUrl`` -{{sso_login_redirect_cs_http_api}} + Clients should validate any requests to the ``redirectUrl``. In particular, it + may be possible for attackers to falsify any query parameters, leading to + cross-site request forgery (CSRF) attacks. + + For example, consider a web-based client at ``https://client.example.com``, + which wants to initiate SSO login on the homeserver at ``server.example.org``. + It does this by storing the homeserver name in a query parameter for the + ``redirectUrl``: it redirects to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=server.example.org``. + + An attacker could trick a victim into following a link to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://client.example.com?hs=evil.com``, + which would result in the client sending a login token for the victim's + account to the attacker-controlled site ``evil.com``. + + To guard against this, clients MUST NOT store state (such as the address of + the homeserver being logged into) anywhere it can be modified by external + processes. + + Instead, the state could be stored in `localStorage + `_ or + in a cookie. + +2. For added security, clients SHOULD include a unique identifier in the + ``redirectUrl`` and reject any callbacks that do not contain a recognised + identifier, to guard against unsolicited login attempts and replay attacks. Server behaviour ----------------- +~~~~~~~~~~~~~~~~ + +Redirecting to the Authentication server +++++++++++++++++++++++++++++++++++++++++ -The URI for the SSO system to be used should be configured on the server by the -server administrator. The server is expected to set up any endpoints required to -interact with that SSO system. For example, for CAS authentication the homeserver -should provide a means for the administrator to configure where the CAS server is -and the REST endpoints which consume the ticket. A good reference for how CAS could -be implemented is available in the older `r0.4.0 version `_ -of this specification. +The server should handle +``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` as follows: -Handling the redirect endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#. It should build a suitable request for the SSO system. -When responding to the ``/login/sso/redirect`` endpoint, the server must -generate a URI for the SSO login page with any appropriate parameters. +#. It should store enough state that the flow can be securely resumed after the + SSO process completes. One way to do this is by storing a cookie which is + stored in the user's browser, by adding a ``Set-Cookie`` header to the response. + +#. It should redirect the user's browser to the SSO login page with the + appropriate parameters. + +See also the "Security considerations" below. .. TODO-spec: @@ -89,24 +178,169 @@ generate a URI for the SSO login page with any appropriate parameters. endpoint, and to give more meaningful errors in the case of faulty/poorly-configured clients. -Handling the authentication endpoint -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Handling the callback from the Authentication server +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Note that there will normally be a single callback URI which is used for both login +and user-interactive authentication: it is up to the homeserver implementation +to distinguish which is taking place. + +The homeserver should validate the response from the SSO system: this may +require additional calls to the authentication server, and/or may require +checking a signature on the response. + +The homeserver then proceeds as follows: + +#. The homeserver MUST map the user details received from the authentication + server to a valid `Matrix user identifier <../appendices.html#user-identifiers>`_. + The guidance in `Mapping from other character sets + <../appendices.html#mapping-from-other-character-sets>`_ may be useful. + +#. If the generated user identifier represents a new user, it should be + registered as a new user. + +#. The homeserver should generate a short-term login token. This is an opaque + token, suitable for use with the ``m.login.token`` type of the |/login|_ + API. The lifetime of this token SHOULD be limited to around five + seconds. + +#. The homeserver adds a query parameter of ``loginToken``, with the value of + the generated login token, to the ``redirectUrl`` given in the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` + request. (Note: ``redirectURL`` may or may not include existing query + parameters. If it already includes one or more ``loginToken`` parameters, + they should be removed before adding the new one.) + +#. The homeserver redirects the user's browser to the URI thus built. + +Security considerations +~~~~~~~~~~~~~~~~~~~~~~~ + +1. Homeservers should ensure that login tokens are not sent to malicious + clients. + + For example, consider a homeserver at ``server.example.org``. An attacker tricks + a victim into following a link to + ``https://server.example.org/login/sso/redirect?redirectUrl=https://evil.com``, + resulting in a login token being sent to the attacker-controlled site + ``evil.com``. This is a form of cross-site request forgery (CSRF). + + To mitigate this, Homeservers SHOULD confirm with the user that they are + happy to grant access to their matrix account to the site named in the + ``redirectUrl``. This can be done either *before* redirecting to the SSO + login page when handling the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect`` endpoint, or + *after* login when handling the callback from the authentication server. (If + the check is performed before redirecting, it is particularly important that + the homeserver guards against unsolicited authentication attempts as below). + + It may be appropriate to whitelist a set of known-trusted client URLs in + this process. In particular, the homeserver's own `login fallback`_ + implementation could be excluded. + +2. For added security, homeservers SHOULD guard against unsolicited + authentication attempts by tracking pending requests. One way to do this is + to set a cookie when handling + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect``, which is + checked and cleared when handling the callback from the authentication + server. + +SSO during User-Interactive Authentication +------------------------------------------ + +`User-interactive authentication`_ is used by client-server +endpoints which require additional confirmation of the user's identity (beyond +holding an access token). Typically this means that the user must re-enter +their password, but for homeservers which delegate to an SSO server, this means +redirecting to the authentication server during user-interactive auth. + +The implemementation of this is based on the `Fallback`_ mechanism for +user-interactive auth. + +Client behaviour +---------------- + +Clients do not need to take any particular additional steps beyond ensuring +that the fallback mechanism has been implemented, and treating the +``m.login.sso`` authentication type the same as any other unknown type +(i.e. they should open a browser window for +``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web?session=``. +Once the flow has completed, the client retries the request with the session +only.) + +Server behaviour +---------------- + +Redirecting to the Authentication server +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The server should handle +``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web`` in +much the same way as +``/_matrix/client/%CLIENT_MAJOR_VERSION%/login/sso/redirect``, which is to say: + +#. It should build a suitable request for the SSO system. + +#. It should store enough state that the flow can be securely resumed after the + SSO process completes. One way to do this is by storing a cookie which is + stored in the user's browser, by adding a ``Set-Cookie`` header to the response. + +#. It should redirect the user's browser to the SSO login page with the + appropriate parameters. + +See also the "Security considerations" below. + +Handling the callback from the Authentication server +++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Note that there will normally be a single callback URI which is used for both login +and user-interactive authentication: it is up to the homeserver implementation +to distinguish which is taking place. + +The homeserver should validate the response from the SSO system: this may +require additional calls to the authentication server, and/or may require +checking a signature on the response. + +The homeserver then returns the `user-interactive authentication fallback +completion`_ page to the user's browser. + +Security considerations ++++++++++++++++++++++++ + +1. Confirming the operation + + The homeserver SHOULD confirm that the user is happy for the operation to go + ahead. The goal of the user-interactive authentication operation is to guard + against a compromised ``access_token`` being used to take over the user's + account. Simply redirecting the user to the SSO system is insufficient, + since they may not realise what is being asked of them, or the SSO system + may even confirm the authentication automatically. + + For example, the homeserver might serve a page with words to the effect of: + + A client is trying to remove a device from your account. To confirm this + action, re-authenticate with single sign-on. If you did not expect this, your + account may be compromised! -Once the homeserver has verified the user's identity with the SSO system, it -MUST map the user ID to a valid `Matrix user identifier <../index.html#user-identifiers>`_. -The guidance in `Mapping from other character sets -<../index.html#mapping-from-other-character-sets>`_ may be useful. + This confirmation could take place before redirecting to the SSO + authentication page (when handling the + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web`` + endpoint), or *after* authentication when handling the callback from the + authentication server. (If the check is performed before redirecting, it is + particularly important that the homeserver guards against unsolicited + authentication attempts as below). -If the generated user identifier represents a new user, it should be registered -as a new user. +2. For added security, homeservers SHOULD guard against unsolicited + authentication attempts by tracking pending requests. One way to do this is + to set a cookie when handling + ``/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/m.login.sso/fallback/web``, + which is checked and cleared when handling the callback from the + authentication server. -Finally, the server should generate a short-term login token. The generated -token should be a macaroon, suitable for use with the ``m.login.token`` type of -the |/login|_ API, and `token-based interactive login <#token-based>`_. The -lifetime of this token SHOULD be limited to around five seconds. This token is -given to the client via the ``loginToken`` query parameter previously mentioned. +.. |GET /login| replace:: ``GET /login`` +.. _GET /login: #get-matrix-client-%CLIENT_MAJOR_VERSION%-login .. |/login| replace:: ``/login`` .. _/login: #post-matrix-client-%CLIENT_MAJOR_VERSION%-login .. |/login/sso/redirect| replace:: ``/login/sso/redirect``