[Pkg-mailman-hackers] [Mailman-cabal] Potential security flaw in Postorius
Pierre-Elliott Bécue
becue at crans.org
Tue Dec 26 17:17:48 UTC 2017
Le lundi 25 décembre 2017 à 13:44:46-0800, Abhilash Raj a écrit :
> (Adding debian maintainers to the CC list)
>
> There was a vulnerability found in Postorius (all released versions) which would set a users password to their Name (display_name attribute of Django User object) in Mailman Core.
>
> Note that Core and Django have separate notion of users and passwords and are loosely coupled using their email addresses only. When a user signs up in Django, a corresponding user record may be created in Core, with the email and display name of the user. However, this bug caused the display name to be None and password be set to display name in Core.
>
> Currently, there are no use cases of a user's password in Core. When using only Postorius, users aren't even aware of this password. However, it may find a use case sometime in future, because of which, I have added a new command in Postorius to reset those passwords. This command should be run in the upgrade process.
>
> $ python manage.py reset_passwords
>
> The patch also includes the fix for the vulnerability.
Dear Abhilash,
Thanks for your CC-ing.
@mejo, I suggest we make a debian patch until upstream releases a new
version.
Maybe the patch should only include postorius/models.py changes.
--
Pierre-Elliott Bécue
GPG: 9AE0 4D98 6400 E3B6 7528 F493 0D44 2664 1949 74E2
> diff --git a/src/postorius/management/commands/reset_passwords.py b/src/postorius/management/commands/reset_passwords.py
> new file mode 100644
> index 0000000..a7d2433
> --- /dev/null
> +++ b/src/postorius/management/commands/reset_passwords.py
> @@ -0,0 +1,70 @@
> +# -*- coding: utf-8 -*-
> +# Copyright (C) 2017 by the Free Software Foundation, Inc.
> +#
> +# This file is part of Postorius.
> +#
> +# Postorius is free software: you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation, either version 3 of the License, or (at your option)
> +# any later version.
> +#
> +# Postorius is distributed in the hope that it will be useful, but WITHOUT
> +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> +# more details.
> +#
> +# You should have received a copy of the GNU General Public License along with
> +# Postorius. If not, see <http://www.gnu.org/licenses/>.
> +#
> +
> +import os
> +import base64
> +
> +from django.core.management.base import BaseCommand
> +from django_mailman3.lib.mailman import get_mailman_client
> +
> +PASSWORD_BYTES = 32
> +
> +
> +class Command(BaseCommand):
> +
> + help = '''Reset passwords of all users in Mailman Core. This does not affect
> + the login passwords of users in Django or any other social
> + authentication. Users will be able to login with their current
> + passwords. Mailman Core maintains a second set of passwords for
> + every user, which would be set to a random value of base64 encode
> + 32 bytes.
> + '''
> +
> + def handle(self, *args, **kwargs):
> + client = get_mailman_client()
> + for user in self._get_all_users(client):
> + self._reset_password(user)
> +
> + def _get_all_users(self, client):
> + """Given a mailmanclient.Client instance, returns an iterator of
> + paginated user records.
> + """
> + page = client.get_user_page(count=50, page=1)
> + while True:
> + for user in page:
> + yield user
> + if page.has_next:
> + page = page.next
> + else:
> + break
> +
> + def _reset_password(self, user):
> + """Given a mailmanclient.restobject.user.User object, reset its password
> + to None in the database.
> + """
> + user.password = self._get_random_password()
> + user.save()
> + msg = 'Password reset for {}'.format(user)
> + self.stdout.write(self.style.SUCCESS(msg))
> +
> + def _get_random_password(self):
> + """Generate a random password for a user.
> + """
> + tok = os.urandom(PASSWORD_BYTES)
> + return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii')
> diff --git a/src/postorius/models.py b/src/postorius/models.py
> index b72d483..2d0d5c5 100644
> --- a/src/postorius/models.py
> +++ b/src/postorius/models.py
> @@ -150,7 +150,8 @@ class MailmanUserManager(MailmanRestManager):
> super(MailmanUserManager, self).__init__('user', 'users')
>
> def create_from_django(self, user):
> - return self.create(user.email, user.get_full_name())
> + return self.create(
> + email=user.email, password=None, display_name=user.get_full_name())
>
> def get_or_create_from_django(self, user):
> try:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-mailman-hackers/attachments/20171226/71766bb9/attachment.sig>
More information about the Pkg-mailman-hackers
mailing list