Account takeover via misconfigured SSO [OIDC] implementation
How we got there
A story about how an OIDC login provider without email confirmation allowed me takeover accounts on a different web app.
This was on a particular friday evening after reading an interesting writeup about Oauth security issues that lead to account takeover, i decided to test the new knowledge on a target i had seen supported Oauth2 login.
My target lets call it xboy.me
was intersting as it had a few applications in scope, lets call them court-app.xboy.me
and tennis-app.xboy.me
. Now court-app.xboy.me
supported various Oauth2 methods like google, etc. However tennis-app.xboy.me
had only two login options (1) username/email and password via Cognito (2) Oauth2 OIDC [from court-app.xboy.me
] via Cognito.
OIDC =
OpenID Connect (OIDC) is an identity layer built on top of the OAuth 2.0 framework. It allows third-party applications to verify the identity of the end-user and to obtain basic user profile information. OIDC uses JSON web tokens (JWTs), which you can obtain using flows conforming to the OAuth 2.0 specifications.
by https://auth0.com/docs/authenticate/protocols/openid-connect-protocol#:~:text=OpenID%20Connect%20(OIDC)%20is%20an,to%20the%20OAuth%202.0%20specifications.
The web application at https://court-app.xboy.me/
uses custom user authentication/registration which allows users to signup/register accounts and use them without email activation/confirmation, while https://tennis-app.xboy.me
uses AWS cognito, which ensures users confirm their emails before using the account.
The web app https://tennis-app.xboy.me
also uses Oauth2 (OIDC) from https://court-app.xboy.me/
which as i said allows unverified users to use the web app.
Heres how the tennis-app.xboy.me
OIDC flow goes
user goes to
https://tennis-app.xboy.me
=> clicks login via oauth =>https://tennis-app.xboy.me
oauth request tohttps://tennis-app.auth.us-west-1.amazoncognito.com/oauth2/authorize
=> gets redirected tohttps://court-app.xboy.me/oauth2/authenticate
=> gets redirected tohttps://court-app.xboy.me/api/oauth2/authorize?
=>https://tennis-app.xboy.me/oauth2?
=> gets redirected tohttps://court-app.xboy.me/oauth2/idpresponse?
=> gets redirected to =>https://tennis-app.auth.us-west-1.amazoncognito.com/oauth2/idpresponse?
=> gets redirected tohttps://tennis-app.xboy.me/oauth/success?
=>https://tennis-app.auth.us-west-1.amazoncognito.com/oauth2/token
[post request to get access token]
What goes on
When a user clicks on login via court-app
the flow fetches the required token and info from court-app
and everything is well and expected.
However instead of logging in the user directly an account is created with the court-app
details and this account is not the same as the one we need to takeover. However a weird behaviour happens.
The weird behaviour
Ater a successful account creation with court-app
details, the https://tennis-app.xboy.me
web app sends a post request https://tennis-app.xboy.me/api/token/refresh
with the idToken param containing the jwt created after the account creation.
This is where things go really wrong really fast as we get logged out for a momment and before we know it we get logged in as the victim.
This is due to a misconfigured OIDC [i believe] it takes in a few params including a JWT TOKEN Created by the oauth2 follow.
Reproduction Steps
The attack goes as follows;
So basically the takeover works as flows, User is registered at https://tennis-app.xboy.me
only and not https://court-app.xboy.me/
=> We (attacker) register at https://court-app.xboy.me/
=> after successfull registration (no email verification) we go to https://tennis-app.xboy.me
and select the Oauth2 (OIDC) login option and we get logged into the victim account after a moment
i.e user registers at
https://tennis-app.xboy.me
with "[email protected]" and password "#sup3rs3cur3P4ss$", confirms account and starts to use it, as attackers we just head tohttps://court-app.xboy.me/
and register an account with "[email protected]" and password "#@Password-1234" but we don't need to confirm the email. we then head tohttps://tennis-app.xboy.me
and select the Oauth2 (OIDC) login option and we get wait for the accounts to be merged
Reproduction is as simple as;
- Go to
https://tennis-app.xboy.me
and create an account with an email not registered athttps://court-app.xboy.me
- Log out on completion
- Go to
https://court-app.xboy.me
and create an account with the above email and finish the set up [wont ask for verification] - Head back to
https://tennis-app.xboy.me
and click login withcourt-app
observe the flow and at the end you have you account takeover
Report
I quickly made a detailed report with as much explanation as i could and submitted. report got triaged in less than two hours as a critical and got awarded €€€€ bounty.
Contacts
@github @twitter @LinkedIn @Intigriti @hackerone_old
🔥🔥: 0