CVE-2023-46138: Weak Password Recovery Mechanism for Forgotten Password (CWE-640)
value: JumpServer is an open source bastion host and maintenance security audit system that complies with 4A specifications. Prior to version 3.8.0, the default email for initial user admin is `admin[@]mycompany[.]com`, and users reset their passwords by sending an email. Currently, the domain `mycompany.com` has not been registered. However, if it is registered in the future, it may affect the password reset functionality. This issue has been patched in version 3.8.0 by changing the default email domain to `example.com`. Those who cannot upgrade may change the default email domain to `example.com` manually.
CWE description: The product contains a mechanism for users to recover or change their passwords without knowing the original password, but the mechanism is weak.
CVSS v3 base score: 5.3
Published: 2023-10-31T00:15Z
Repository: https://github.com/jumpserver/jumpserver
Language: Python
Files changed: apps/common/tasks.py, apps/users/migrations/0046_auto_20230927_1456.py
Commit date: 2023-09-27 15:15:15 +0800
Commit message: perf: 修改默认的邮箱地址

Diff: diff --git a/apps/common/tasks.py b/apps/common/tasks.py
index 2daa5acb5..468fa2a51 100644
--- a/apps/common/tasks.py
+++ b/apps/common/tasks.py
@@ -35,13 +35,11 @@ def send_mail_async(*args, **kwargs):
         args = list(args)
         args[0] = (settings.EMAIL_SUBJECT_PREFIX or '') + args[0]
         from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
         args.insert(2, from_email)
 
-    args[3] = [mail for mail in args[3] if mail != 'admin@mycomany.com']
     args = tuple(args)
-
     try:
         return send_mail(*args, **kwargs)
     except Exception as e:
         logger.error("Sending mail error: {}".format(e))
 
@@ -50,11 +48,10 @@ def send_mail_async(*args, **kwargs):
 def send_mail_attachment_async(subject, message, recipient_list, attachment_list=None):
     if attachment_list is None:
         attachment_list = []
     from_email = settings.EMAIL_FROM or settings.EMAIL_HOST_USER
     subject = (settings.EMAIL_SUBJECT_PREFIX or '') + subject
-    recipient_list = [mail for mail in recipient_list if mail != 'admin@mycomany.com']
     email = EmailMultiAlternatives(
         subject=subject,
         body=message,
         from_email=from_email,
         to=recipient_list
diff --git a/apps/users/migrations/0046_auto_20230927_1456.py b/apps/users/migrations/0046_auto_20230927_1456.py
new file mode 100644
index 000000000..d32569026
--- /dev/null
+++ b/apps/users/migrations/0046_auto_20230927_1456.py
@@ -0,0 +1,21 @@
+# Generated by Django 4.1.10 on 2023-09-27 06:56
+
+from django.db import migrations
+
+
+def migrate_user_default_email(apps, *args):
+    user_cls = apps.get_model('users', 'User')
+    user_cls.objects\
+        .filter(email='admin@mycomany.com')\
+        .update(email='admin@example.com')
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('users', '0045_delete_usersession'),
+    ]
+
+    operations = [
+        migrations.RunPython(migrate_user_default_email),
+    ]

Vulnerable code:     args[3] = [mail for mail in args[3] if mail != 'admin@mycomany.com']

    recipient_list = [mail for mail in recipient_list if mail != 'admin@mycomany.com']
Fixed code: # Generated by Django 4.1.10 on 2023-09-27 06:56

from django.db import migrations


def migrate_user_default_email(apps, *args):
    user_cls = apps.get_model('users', 'User')
    user_cls.objects\
        .filter(email='admin@mycomany.com')\
        .update(email='admin@example.com')


class Migration(migrations.Migration):

    dependencies = [
        ('users', '0045_delete_usersession'),
    ]

    operations = [
        migrations.RunPython(migrate_user_default_email),
    ]