A Letter to the Authors of Web Authentication Libraries

21 views
Skip to first unread message

Paul Johnston

unread,
May 2, 2009, 11:27:30 PM5/2/09
to Django developers
Hi,

Many web sites have a user name and password login system, and do not
use SSL. As a consequence, users' passwords are transmitted over the
internet unencrypted. This puts them at risk, particularly if the user
is on a shared ethernet segment, or open wireless network.

For many years I have provided a JavaScript MD5 library (http://
pajhome.org.uk/crypt/md5/), which can be used to perform a challenge-
response login. This avoids passwords being transmitted unencrypted,
although the security is not as strong as SSL. A number of web sites
currently use this technique; for some years Yahoo did, although they
now have SSL login.

However, the use of JavaScript MD5 is not widespread. I think this is
because few authentication libraries support it. It is possible for a
library to provide JavaScript MD5 as an authentication mechanism, with
the details hidden from the application developer. In fact, it's quite
easy to implement, and there is a lot of guidance on my site.

So, this is a call to the authors of all web authentication libraries.
Add JavaScript MD5 as an authentication mechanism. And then let me
know, so I can link to you from my site. If you need any help
implementing it, drop me a line, I'll do what I can.

I think supporting this mode would be a big selling point for any
authentication library. And if support becomes widespread, the
internet becomes a little bit safer for everyone.

Best wishes,

Paul

Jerome Leclanche

unread,
May 3, 2009, 12:52:47 AM5/3/09
to django-d...@googlegroups.com
Is there a fallback to normal auth possible if js is not running? I
like the idea, but preventing someone who doesn't have js enabled to
register/auth is pretty harsh.
--
Adys

James Bennett

unread,
May 3, 2009, 1:09:42 AM5/3/09
to django-d...@googlegroups.com
On Sat, May 2, 2009 at 11:27 PM, Paul Johnston <paul...@gmail.com> wrote:
> However, the use of JavaScript MD5 is not widespread. I think this is
> because few authentication libraries support it. It is possible for a
> library to provide JavaScript MD5 as an authentication mechanism, with
> the details hidden from the application developer. In fact, it's quite
> easy to implement, and there is a lot of guidance on my site.

I think it is not widespread because it is not in any way whatsoever
an improvement when compared to sending credentials in the clear over
a non-secure connection. The only options are SSL or more complicated
protocols which do not use the transmission of a single password or
password-like credential.


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

M. N. Islam Shihan

unread,
May 3, 2009, 3:51:51 AM5/3/09
to django-d...@googlegroups.com
It should be possible to provide a fallback to go with unencrypted
authentication @ server side depending on whether a flag set at client
side by javascript (using cookie or hidden field).

Anyway, the only limitation of this technique i see is it can't be
used in cases where the oneway hashing alhorithm to encrypt password @
server side is not md5, that in turn will limit the versatile nature
of choosing password encryption mechanism provided by a web
development framework like django.

Regards,
M N Islam Shihan

Elliott

unread,
May 3, 2009, 5:49:18 AM5/3/09
to Django developers
On May 3, 2:51 am, "M. N. Islam Shihan" <mnis4...@gmail.com> wrote:
> It should be possible to provide a fallback to go with unencrypted  
> authentication @ server side depending on whether a flag set at client  
> side by javascript (using cookie or hidden field).
>
> Anyway, the only limitation of this technique i see is it can't be  
> used in cases where the oneway hashing alhorithm to encrypt password @  
> server side is not md5, that in turn will limit the versatile nature  
> of choosing password encryption mechanism provided by a web  
> development framework like django.
>
> Regards,
> M N Islam Shihan
This shouldn't be a concern, as the other hashing methods should be
able to be implemented in js as well.

The real problem is that the method used, as well as the salt, are
stored on a per-user basis. Both of these would need to be known by
the js in order to properly hash the password, but they cannot be
known without first knowing which user was attempting to log in. That
complicates things a lot, because now you have to send in a user ID
and get back a method/salt. That throws out the whole "don't reveal
whether a user with this username actually exists" thing. You can fix
that by generating a randomized response if the user doesn't exist etc
etc, and you just have more and more complications down the line, with
more and more data being sent back and forth for one login.

In short, there is no simple way within django to encrypt logins with
django's authentication system.

M. N. Islam Shihan

unread,
May 3, 2009, 6:16:24 AM5/3/09
to django-d...@googlegroups.com
Exactly!! Besides the one way hashing algorithms, salt based
algorithms are also not be feasible to go with this strategy.

Thanx for clarifying this side aa well.

Regards,
M N Islam Shihan

Paul Johnston

unread,
May 3, 2009, 9:34:12 AM5/3/09
to Django developers
Hi,

So Django hashes passwords server-side with a per-user salt? In that
case you do need an Ajax request at login to do the hashing. It's easy
enough to create a random (but consistent) response for non-existing
users. Or you could make it a configuration option whether Django uses
per-user or per-site salts - the security benefits of per-user salts
are minor.

To answer the other points:
1) Making this fall back to unencrypted when JS is disabled is no
problem.
2) It does have security benefits over a plaintext password. The
response is not a password-like credential; it is only valid for one
login (or the timeout period, if used in stateless mode). If you don't
understand this, read up on challenge-response login.

Paul

Ludvig Ericson

unread,
May 3, 2009, 12:54:35 PM5/3/09
to django-d...@googlegroups.com
On May 3, 2009, at 15:34, Paul Johnston wrote:

> the security benefits of per-user salts are minor.

No.

- Ludvig

Glenn Maynard

unread,
May 3, 2009, 5:21:07 PM5/3/09
to django-d...@googlegroups.com
On Sun, May 3, 2009 at 5:49 AM, Elliott <Join.T...@gmail.com> wrote:
> The real problem is that the method used, as well as the salt, are
> stored on a per-user basis. Both of these would need to be known by
> the js in order to properly hash the password, but they cannot be
> known without first knowing which user was attempting to log in. That
> complicates things a lot, because now you have to send in a user ID
> and get back a method/salt. That throws out the whole "don't reveal
> whether a user with this username actually exists" thing. You can fix
> that by generating a randomized response if the user doesn't exist etc
> etc, and you just have more and more complications down the line, with
> more and more data being sent back and forth for one login.

You need to requeste a challenge anyway. The challenge would include
a hash type, the password salt, and the challenge salt. The response
would look like HASH(challenge_salt + HASH(password_salt + password)).
That's not much more complicated than it'd be without a password
salt, except for needing to implement a hash or two in JS (which has,
no doubt, already been done).

One other detail on the server-side: if you're sending a randomized
response for a nonexistant user, it must use the same fake, random
password_salt each time--else you could tell that the user doesn't
exist due to the password_salt changing on each attempt. Just use
SHA1(SECRET_KEY + attempted_name).

That said, while I do think there's a benefit to this, the login is
still going to end up in a session cookie (whether with Django's
approach or any other), and there's no way to keep people from just
stealing that cookie (locking it to the IP only makes it a little
harder, and also more inconvenient for people on rapidly changing
dynamic IPs). It also doesn't deal with the need to send a new
password, when changing one or creating a new account. You'd still
need SSL to do that securely, and once you've bought a certificate and
have SSL set up, there's no need for this anyway.

There's still a benefit, because you're sending passwords in the clear
much less frequently--an imperfect improvement is still an
improvement. (Similarly, self-signed SSL certificates are much more
secure than plaintext, despite what your browser's ill-conceived
warnings might want you to believe.) But with these limitations, it
may not be worth the bother for most people.

--
Glenn Maynard

Paul Johnston

unread,
May 4, 2009, 9:10:15 AM5/4/09
to Django developers
Hi,

> There's still a benefit, because you're sending passwords in the clear
> much less frequently--an imperfect improvement is still an
> improvement.  (Similarly, self-signed SSL certificates are much more
> secure than plaintext, despite what your browser's ill-conceived
> warnings might want you to believe.)  But with these limitations, it
> may not be worth the bother for most people.

Yep, that's exactly it, it has limitations, but is an improvement.

If my authentication library supported this out of the box, it would
be no bother, and worth it for most people.

Paul

Zain Memon

unread,
May 4, 2009, 3:50:50 PM5/4/09
to django-d...@googlegroups.com
If you want to get this into Django, I think you'll need to provide a solid proof of concept that shows you can work around the objections raised in this thread (graceful degradation, backwards compatibility) and, more importantly, that shows this is something actually useful and wanted.

It would be pretty easy for you to create a custom widget and authentication back-end that uses your library. Package it up, throw it on github, and see what people think. You don't need permission from the Django devs to do that.

Zain

Paul Johnston

unread,
May 5, 2009, 3:41:20 PM5/5/09
to Django developers
Hi,

> If you want to get this into Django, I think you'll need to provide a solid
> proof of concept that shows you can work around the objections raised in
> this thread (graceful degradation, backwards compatibility) and, more
> importantly, that shows this is something actually useful and wanted.

Ok, fair comment. I do plan to add this to repoze.who, but no plans
for Django. The JavaScript library and instructions are there if you
guys want them, but that's it.

Thanks for the lively discussion,

Paul
Reply all
Reply to author
Forward
0 new messages