Don't check the `at_hash` (access token hash) in OIDC ID Tokens if we don't use the access token (#18374)
Co-authored-by: Eric Eastwood <erice@element.io>
1 files changed, 27 insertions, 2 deletions
diff --git a/synapse/handlers/oidc.py b/synapse/handlers/oidc.py
index c4cf0636a3..fb759172b3 100644
--- a/synapse/handlers/oidc.py
+++ b/synapse/handlers/oidc.py
@@ -587,6 +587,24 @@ class OidcProvider:
)
@property
+ def _uses_access_token(self) -> bool:
+ """Return True if the `access_token` will be used during the login process.
+
+ This is useful to determine whether the access token
+ returned by the identity provider, and
+ any related metadata (such as the `at_hash` field in
+ the ID token), should be validated.
+ """
+ # Currently, Synapse only uses the access_token to fetch user metadata
+ # from the userinfo endpoint. Therefore we only have a single criteria
+ # to check right now but this may change in the future and this function
+ # should be updated if more usages are introduced.
+ #
+ # For example, if we start to use the access_token given to us by the
+ # IdP for more things, such as accessing Resource Server APIs.
+ return self._uses_userinfo
+
+ @property
def issuer(self) -> str:
"""The issuer identifying this provider."""
return self._config.issuer
@@ -957,9 +975,16 @@ class OidcProvider:
"nonce": nonce,
"client_id": self._client_auth.client_id,
}
- if "access_token" in token:
+ if self._uses_access_token and "access_token" in token:
# If we got an `access_token`, there should be an `at_hash` claim
- # in the `id_token` that we can check against.
+ # in the `id_token` that we can check against. Setting this
+ # instructs authlib to check the value of `at_hash` in the
+ # ID token.
+ #
+ # We only need to verify the access token if we actually make
+ # use of it. Which currently only happens when we need to fetch
+ # the user's information from the userinfo_endpoint. Thus, this
+ # check is also gated on self._uses_userinfo.
claims_params["access_token"] = token["access_token"]
claims_options = {"iss": {"values": [metadata["issuer"]]}}
|