VYPR
Medium severityOSV Advisory· Published Oct 9, 2025· Updated Apr 15, 2026

CVE-2025-61783

CVE-2025-61783

Description

Python Social Auth is a social authentication/registration mechanism. In versions prior to 5.6.0, upon authentication, the user could be associated by e-mail even if the associate_by_email pipeline was not included. This could lead to account compromise when a third-party authentication service does not validate provided e-mail addresses or doesn't require unique e-mail addresses. Version 5.6.0 contains a patch. As a workaround, review the authentication service policy on e-mail addresses; many will not allow exploiting this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
social-auth-app-djangoPyPI
< 5.6.05.6.0

Affected products

1

Patches

1
10c80e2ebabe

fix: avoid associating with existing user when creating fails

2 files changed · +15 14
  • social_django/storage.py+6 10 modified
    @@ -9,6 +9,7 @@
     from django.core.exceptions import FieldDoesNotExist
     from django.db import router, transaction
     from django.db.utils import IntegrityError
    +from social_core.exceptions import AuthAlreadyAssociated
     from social_core.storage import (
         AssociationMixin,
         BaseStorage,
    @@ -81,20 +82,15 @@ def create_user(cls, *args, **kwargs):
                         cls.user_model()._meta.get_field("username")  # noqa: SLF001
                     except FieldDoesNotExist:
                         kwargs.pop("username")
    +
    +        # If the create fails below due to an IntegrityError, ensure that the transaction
    +        # stays undamaged by wrapping the create in an atomic.
    +        using = router.db_for_write(cls.user_model())
             try:
    -            # If the create fails below due to an IntegrityError, ensure that the transaction
    -            # stays undamaged by wrapping the create in an atomic.
    -            using = router.db_for_write(cls.user_model())
                 with transaction.atomic(using=using):
                     return manager.create_user(*args, **kwargs)
             except IntegrityError as exc:
    -            # If email comes in as None it won't get found in the get
    -            if kwargs.get("email", True) is None:
    -                kwargs["email"] = ""
    -            try:
    -                return manager.get(*args, **kwargs)
    -            except cls.user_model().DoesNotExist:
    -                raise exc from None
    +            raise AuthAlreadyAssociated(None) from exc
     
         @classmethod
         def filter_users(cls, *args, **kwargs) -> QuerySet:
    
  • tests/test_models.py+9 4 modified
    @@ -5,6 +5,7 @@
     from django.core.management import call_command
     from django.db import IntegrityError
     from django.test import TestCase, override_settings
    +from social_core.exceptions import AuthAlreadyAssociated
     
     from social_django.models import (
         AbstractUserSocialAuth,
    @@ -101,18 +102,22 @@ def test_get_username(self):
             self.assertEqual(UserSocialAuth.get_username(self.user), self.user.username)
     
         def test_create_user(self):
    -        # Catch integrity error and find existing user
    -        UserSocialAuth.create_user(username=self.user.username)
    +        UserSocialAuth.create_user(username="testuser")
     
         def test_create_user_reraise(self):
    -        with self.assertRaises(IntegrityError):
    +        with self.assertRaises(AuthAlreadyAssociated):
                 UserSocialAuth.create_user(username=self.user.username, email=None)
     
         @mock.patch("social_django.models.UserSocialAuth.username_field", return_value="email")
    -    @mock.patch("django.contrib.auth.models.UserManager.create_user", side_effect=IntegrityError)
    +    @mock.patch("django.contrib.auth.models.UserManager.create_user", return_value="<User>")
         def test_create_user_custom_username(self, *args):
             UserSocialAuth.create_user(username=self.user.email)
     
    +    @mock.patch("django.contrib.auth.models.UserManager.create_user", side_effect=IntegrityError)
    +    def test_create_user_existing(self, *args):
    +        with self.assertRaises(AuthAlreadyAssociated):
    +            UserSocialAuth.create_user(username=self.user.email)
    +
         def test_get_user(self):
             self.assertEqual(UserSocialAuth.get_user(pk=self.user.pk), self.user)
             self.assertIsNone(UserSocialAuth.get_user(pk=123))
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.