Not logged in

V2: Classic-Federated Merge Medium

The victim has a legitimate verified account. The service silently merges any SSO provider that asserts the same email - no re-authentication, no consent prompt, no notification.

Attacker precondition: the ability to issue an OAuth token for the victim's email at any SSO provider the service trusts:

The attack only needs to work at one provider. Every SSO option added is another permanent trust delegation on every account - including accounts that never used that provider.

/auth/sso/callback
// /auth/sso/callback router.get('/auth/sso/callback', async (req, res) => { const { email, provider } = parseOAuthToken(req.query.code) const user = await db.users.findByEmail(email) if (user && user.emailVerified) { // BUG: no re-authentication required before linking a new provider. // Any OAuth assertion from any trusted provider silently gains access // to this account. The user is never notified. Works even if they // never set up SSO - every provider the app trusts is an implicit // access path to every account on the platform. await db.users.update(user.id, { ssoProviders: [...user.ssoProviders, provider], }) return createSession(res, user.id) } const newUser = await db.users.create({ email, emailVerified: true, ssoProviders: [provider] }) createSession(res, newUser.id) })

1

Victim: registers normally victim

Create a legitimate account with email and password.

Password will be set to Password123

2

Attacker: exploits a trusted provider attacker

The attacker does not touch the target service. They only need access at one of the providers it trusts. Pick a scenario:

As a provider insider with token-issuance access:

Via a provider breach or token forgery: