Prevent OAuth relinking.
When an OAuth provider_user_id is already linked to User A, and User B authenticates with the same OAuth identity, User B is silently logged in as User A. This is by design for single-user OAuth, but in a multi-user environment it means: if an attacker gains access to the same OAuth provider account (e.g., a shared GitHub org account, or by compromising the OAuth provider), they can log in as the linked Calibre-Web user with no password needed.
This commit is contained in:
@@ -134,6 +134,14 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider
|
|||||||
oauth_entry = query.first()
|
oauth_entry = query.first()
|
||||||
# already bind with user, just login
|
# already bind with user, just login
|
||||||
if oauth_entry.user:
|
if oauth_entry.user:
|
||||||
|
# If a user is already logged in and it's a different account, reject the link
|
||||||
|
# to prevent account takeover via shared OAuth identities
|
||||||
|
if current_user and current_user.is_authenticated and oauth_entry.user_id != current_user.id:
|
||||||
|
flash(_("This %(oauth)s account is already linked to a different user",
|
||||||
|
oauth=provider_name), category="error")
|
||||||
|
log.warning("User %s tried to link OAuth account already bound to user %s",
|
||||||
|
current_user.id, oauth_entry.user_id)
|
||||||
|
return redirect(url_for('web.profile'))
|
||||||
login_user(oauth_entry.user)
|
login_user(oauth_entry.user)
|
||||||
log.debug("You are now logged in as: '%s'", oauth_entry.user.name)
|
log.debug("You are now logged in as: '%s'", oauth_entry.user.name)
|
||||||
flash(_("Success! You are now logged in as: %(nickname)s", nickname=oauth_entry.user.name),
|
flash(_("Success! You are now logged in as: %(nickname)s", nickname=oauth_entry.user.name),
|
||||||
|
|||||||
Reference in New Issue
Block a user