Killing off (default) legacy md5 password support before 1.0

18 views
Skip to first unread message

James Bennett

unread,
Mar 22, 2008, 4:00:40 AM3/22/08
to django-d...@googlegroups.com
Since there's been some discussion of things to do before 1.0, I'd
like to throw in my own request for a pony and see if anyone thinks
it'd be useful:

Right now, django.contrib.auth.models.User.check_password does some
legacy handling behind the scenes; way back in the Elder Days,
passwords were unsalted md5 hashes, not the salted "choose your own
hash" system we use now, and so there's a bit of code in there which
transparently migrates old unsalted md5 password hashes to salted
SHA1. It seems like that'd be nice to kill off, and I'm thinking it
could be done using a two-part scheme:

First, provide an auth backend which does two checks: first is the
standard check assuming a salted hash, currently performed by the
ModelBackend. If that fails, it tries again as unsalted md5, and if
that returns a User it does the behind-the-scenes update.

Second, yank the legacy code out of the User model and tell people who
are upgrading or who've otherwise been around long enough to worry
about this that they should drop in the above-mentioned backend.

This gets rid of the legacy wart while providing a simple and
non-breaking path forward; the auth backend that handles the legacy
passwords could probably be phased out in a controlled fashion, or
just made available as a third-party component for people who need to
use it indefinitely. And best of all, it wouldn't require much in the
way of actual code to add to Django; the legacy-support backend could
largely delegate to ModelBackend, and only add a small bit of logic
for the special case.

Thoughts?


--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

James Bennett

unread,
Mar 22, 2008, 4:04:03 AM3/22/08
to django-d...@googlegroups.com
On Sat, Mar 22, 2008 at 3:00 AM, James Bennett <ubern...@gmail.com> wrote:
> First, provide an auth backend which does two checks: first is the
> standard check assuming a salted hash, currently performed by the
> ModelBackend. If that fails, it tries again as unsalted md5, and if
> that returns a User it does the behind-the-scenes update.

Or, since I'm an idiot at 3AM, we could just tell people to leave
ModelBackend first, and write a legacy md5 backend that does the
upgrade, and tell people to put that after ModelBackend. Much simpler.

James Bennett

unread,
Mar 22, 2008, 4:40:17 AM3/22/08
to django-d...@googlegroups.com
And since I love replying to myself, I've opened a ticket and attached
a quick patch which shows what I'm getting at:

http://code.djangoproject.com/ticket/6858

The patch is the simplest thing that can work, and does indeed work
for me locally if I create a user with an unsalted md5 password, add
the new backend, and then try to log in.

Alex Ezell

unread,
Mar 22, 2008, 10:35:09 AM3/22/08
to django-d...@googlegroups.com
On Sat, Mar 22, 2008 at 3:04 AM, James Bennett <ubern...@gmail.com> wrote:
>
> On Sat, Mar 22, 2008 at 3:00 AM, James Bennett <ubern...@gmail.com> wrote:
> > First, provide an auth backend which does two checks: first is the
> > standard check assuming a salted hash, currently performed by the
> > ModelBackend. If that fails, it tries again as unsalted md5, and if
> > that returns a User it does the behind-the-scenes update.
>
> Or, since I'm an idiot at 3AM, we could just tell people to leave
> ModelBackend first, and write a legacy md5 backend that does the
> upgrade, and tell people to put that after ModelBackend. Much simpler.

James, this would be a nice workaround for people migrating a user
base from an older system, even if it wasn't Django. Say a certain
someone needs to migrate the users from an existing PHP system that
uses unsalted md5 passwords, this could be a lot of the work towards a
transparent migration.

Or maybe I'm just being an idiot at 9:33AM. :)

/alex

Reply all
Reply to author
Forward
0 new messages