SSO not using PKCE allowing impersonation
Summary
Since OAuth 2.1, PKCE is required even for confidential client. Your current OIDC client used for making SSO with Google IDP is currently not using PKCE.
Description
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-01#section-9.8
Historic note: Although PKCE [RFC7636] was originally designed as a
mechanism to protect native apps, this advice applies to all kinds of
OAuth clients, including web applications and other confidential
clients.
Clients SHOULD use code challenge methods that do not expose the
"code_verifier" in the authorization request. Otherwise, attackers
that can read the authorization request (cf. Attacker A4 in
(#secmodel)) can break the security provided by this mechanism.
Currently, "S256" is the only such method.
The attack is describe here https://condatis.com/news/blog/oauth-confidential-clients/ It's a targeted attack made possible by first tricking the user in installing a dodgy web browser plugin. Looking at your implementation of OIDC, in particular with SSO, you are not using PKCE yet.
Steps to reproduce
(1. any preconditions in the environment)
The attacker needs to be able to read the authorisation request. This is achievable with a malicious web browser extension
(2. complete HTTP or API request, or)
The web browser extension needs to intercept the callback, extract the auth code and block the request. The victim would be confused by not been logged in but second attempt would let the user login without block any requests => The user will simply think of a glitch and would simply relogin without too much suspicion. The stolen auth code is send to the attacker.
(3. Attacker in action ) The attacker is then login with a legit google account, just to trick google to do the redirect. Once the callback is triggered from google, the attacker replace the legit code by the stolen one. This can be done again with a browser extension. Behind the scene, Gitlab exchange the stolen code into a session, but the ID token returned by google correspond to the victim and the attacker therefore gain a session matching the victim
Gitlab endpoint vulnerability
The callback endpoint https://gitlab.com/users/auth/google_oauth2/callback doesn't prevent replay attack.
PS: the fact that the attacker needs to steal the auth code using a network attack is just the entry point. The real vulnerability is your callback lacking of protection against replay attack.
Impact
If a user get tricked in getting a malicious web browser extention, it's fairly easy to get access to his account. Relevant logs and/or screenshots https://drive.google.com/file/d/1IdG0nu_x1ZcBWAR8jxiAHA6RaBEi_wRm/view?usp=share_link
Possible fixes
- Move from OAuth 2.0 to OAuth 2.1. In particular, enable PKCE on your OpenID flow
- use the Nonce feature in OIDC.
cc @gitlab-com/gl-security/appsec
Describe what you would like to see improved.