[SECURITY] Session Hijacking in Django

831 views
Skip to first unread message

David Ross @ Wolfeon

unread,
Nov 26, 2007, 12:52:52 AM11/26/07
to Django developers
Hello,

I'm requesting someone please fix the code to the sessions module to
make Django secure. Currently Django is vulnerable to session
hijacking. Even though the length of the keys are long, a brute force
attack would not be difficult to gain access to a site until they get
a valid item in the page they're trying to access. Giving the client
two keys makes a site more secure to a point. Users who don't use a
secure connection over SSL are still at risk since packets can be
sniffed, however administrators are expected to force logged in users
to use a secure connection.

1) People have been using this exploit for years
http://www.theregister.co.uk/2005/06/08/hotmail_hack/

2) This means anyone who runs Django and uses the default sessions
module is running an insecure site by design.
There is only 1 key to crack, if the site is a medical database, then
the site would be a target. I do plan to be using Django in a medical
environment, and am rather disgusted at the current state because the
ticket was opened 11 months ago.

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

3) Why is it taking so long to look at needed features and
insecurities like this? My example patch took 8 months for someone to
implement and commit to trunk.

My recommendation is to incorporate code in the default session module
which is included in Django.
http://code.google.com/p/django-signedcookies/

David Ross

James Bennett

unread,
Nov 26, 2007, 1:50:13 AM11/26/07
to django-d...@googlegroups.com
On 11/25/07, David Ross @ Wolfeon <david...@wolfeon.com> wrote:
> I'm requesting someone please fix the code to the sessions module to
> make Django secure.

I'm going to play devil's advocate here, not out of any personal
malice, but simply because it's important to have *someone* do it in a
case like this. Now...

"Secure" is an awfully tricky word. What you're actually asking for is
to have the Django sessions module rewritten to suit your specific
security needs, which is very different from what you're saying.
Please be careful with the word "secure", because there's really no
such thing as a "secure" application[1], only an application which
suits the security needs of the use case it was designed for.

> Currently Django is vulnerable to session
> hijacking. Even though the length of the keys are long, a brute force
> attack would not be difficult to gain access to a site until they get
> a valid item in the page they're trying to access.

Brute-forcing a session is always going to be possible to a greater or
lesser extent. The question here, then, is not "how do we prevent
brute-forcing", but "how difficult do we want to make it" and, by
extension, "how complex do we want to make the default sessions
framework"; the perceived extra security of a different mechanism
would necessarily involve a trade-off of extra complexity in the
sessions framework, and it may not be possible to keep that extra
complexity from showing through in common use cases, so a careful
discussion of whether the gain from make that trade-off is worth the
downside is important to have.

> Giving the client
> two keys makes a site more secure to a point. Users who don't use a
> secure connection over SSL are still at risk since packets can be
> sniffed, however administrators are expected to force logged in users
> to use a secure connection.

If packet sniffing is a worry, SSL is the solution.

> 1) People have been using this exploit for years
> http://www.theregister.co.uk/2005/06/08/hotmail_hack/

People have been using social engineering for even longer; should we
forbid users of Django-based applications from reading email or
talking to strangers on the street (anybody remember the study which
found people would trade their passwords for a chocolate bar?)? ;)

> 2) This means anyone who runs Django and uses the default sessions
> module is running an insecure site by design.

See above about "security", and be very careful about generalizing
from a specific use case; "this does not meet my application's
security needs" does not necessarily equate to "this is insecure by
design".

> There is only 1 key to crack, if the site is a medical database, then
> the site would be a target. I do plan to be using Django in a medical
> environment, and am rather disgusted at the current state because the
> ticket was opened 11 months ago.

The code was implemented as a third-party application, freely
available to anyone who wants or needs to use it. Having proposed
additions to django.contrib -- which is what that patch was -- spend
time first as third-party applications in order to let them evolve and
ensure they're widely-used enough to be good contrib candidates is
generally how Django works.

> 3) Why is it taking so long to look at needed features and
> insecurities like this? My example patch took 8 months for someone to
> implement and commit to trunk.

Again, be careful about generalizing from specific use cases to Django
as a whole. "This is a high priority for my application" does *not*
necessarily translate to "this is a high priority for the Django
framework".

> My recommendation is to incorporate code in the default session module
> which is included in Django.
> http://code.google.com/p/django-signedcookies/

In general, recommendations which come without a confrontational
attitude tend to be more widely appreciated than recommendations which
do.

[1] Actually, a "secure" web application is possible. It just starts
with not ever connecting the application to the Web. Ideally, the
server on which the application code and database is kept will also be
stored inside a nuclear-hardened bunker, guarded 24/7 by military
special forces, and with constant surveillance provided by
intelligence agencies. For maximum security, the server should be
unplugged from electrical connections, have all input devices removed,
and be dismantled, run through magnetic scrambling and burned, with
the combustion by-products and burned remains then ejected into a
convenient singularity to insure the information is removed from this
universe. Security recommendations in this footnote assume you do not
care if entities in other universes are later able to retrieve
sensitive information.


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

Ned Batchelder

unread,
Nov 26, 2007, 7:17:51 AM11/26/07
to django-d...@googlegroups.com
A couple of points:

1) the hotmail_hack story you point to is about cross-site scripting,
which has nothing to do with the security of cookies.
2) the signedcookies code you point to for inclusion in Django
explicitly discusses the idea that sessions are not vulnerable and
therefore their cookies don't need to be signed.

In any case, if the signedcookies code makes you feel better about the
security of your site, you should certainly use it. There's no point in
being "disgusted" at Django as a whole.

--Ned.

Marty Alchin

unread,
Nov 26, 2007, 7:37:52 AM11/26/07
to django-d...@googlegroups.com
On 11/26/07, David Ross @ Wolfeon <david...@wolfeon.com> wrote:
> environment, and am rather disgusted at the current state because the
> ticket was opened 11 months ago.
>
> http://code.djangoproject.com/ticket/3285
>
> My recommendation is to incorporate code in the default session module
> which is included in Django.
> http://code.google.com/p/django-signedcookies/

As that's my code, I think i'm qualified to discuss it a bit. First,
don't pretend I'm some sort of security expert who came in to save the
day for all insecure applications. I wrote that code after a brief
exchange with Simon WIllison when editing the Django Book last winter.
It was my first contribution to Django, as evidenced by the fact that
I started with a patch for a feature that really doesn't need to be
included in trunk at all.

That said, James is right. There's absolutely nothing stopping you
from using the signedcookies code as it stands right now, without
being part of Django proper. That is, after all, the entire point of
releasing it as its own app. I'm glad you think it's a good idea, and
I'd love to hear your experiences with it, so I can improve it based
on your feedback.

As for the actual security of signed cookies, they're still vulnerable
to at least two problems. For one, the signature method is still
susceptible to brute force methods, as you yourself admit that using
two keys only makes it "more secure to a point". To my knowledge,
there's nothing that can be done to completely prevent brute force
attacks like that.

The bigger problem, however, is that signed cookies are perfectly
valid, regardless of which machine they come from. Cookie theft is a
very real problem, and it's something that the signedcookies doesn't
handle at all. It might be possible to incorporate the user's IP in
the signature as well, but I fear that would lock out more people than
it should, if a user's IP changes during a session (yes, it can
happen), or it could be useless behind certain kinds of proxies.

So, to sum up, feel free to use signed cookies if you like, and let me
know what you think. Submit tickets if you have new features or
bugfixes. But don't expect it to be a silver bullet that will
magically secure your application. It certainly helps in most cases,
but it's not a cure-all. If you're as concerned with security as it
sounds like you are, you might look at SecurID.[1]

-Gul

[1] http://en.wikipedia.org/wiki/SecurID

Marty Alchin

unread,
Nov 26, 2007, 7:39:45 AM11/26/07
to django-d...@googlegroups.com
On 11/26/07, James Bennett <ubern...@gmail.com> wrote:
> [1] Actually, a "secure" web application is possible. It just starts
> with not ever connecting the application to the Web. Ideally, the
> server on which the application code and database is kept will also be
> stored inside a nuclear-hardened bunker, guarded 24/7 by military
> special forces, and with constant surveillance provided by
> intelligence agencies. For maximum security, the server should be
> unplugged from electrical connections, have all input devices removed,
> and be dismantled, run through magnetic scrambling and burned, with
> the combustion by-products and burned remains then ejected into a
> convenient singularity to insure the information is removed from this
> universe. Security recommendations in this footnote assume you do not
> care if entities in other universes are later able to retrieve
> sensitive information.

Don't kid yourself. If the Hollywood writers weren't on strike, I bet
Matt Damon could still get in. ;)

-Gul

David Ross @ Wolfeon

unread,
Nov 26, 2007, 7:47:58 AM11/26/07
to Django developers
I can be unclear at times, especially while I'm very tired. I'll have
to make an example of what I'm talking about included with an example
or so. People tend to be a bit more understanding if there is
something there to play with instead of an idea.

I try not to use by IP due to the problem you specified.

The way I think of the second cookie, is more like a 2nd password.
Sure, there is a possibility of a brute force with it to, but it is
less likely they'll brute force a 2nd session id key along with the
first. I see this security method implemented with login mechanisms as
well. Of course, login mechanisms are a bit easier to secure, after
the 5th try, banned. ;)

What would be interesting is to modify the session framework to "ban"
an ip once it has made several Suspicious attempts. What is the point
of raising a Suspicious exception if it does nothing?

David Ross

On Nov 26, 3:37 am, "Marty Alchin" <gulop...@gamemusic.org> wrote:
> The bigger problem, however, is that signed cookies are perfectly
> valid, regardless of which machine they come from. Cookie theft is a
> very real problem, and it's something that the signedcookies doesn't
> handle at all. It might be possible to incorporate the user's IP in
> the signature as well, but I fear that would lock out more people than
> it should, if a user's IP changes during a session (yes, it can
> happen), or it could be useless behind certain kinds of proxies.
>
> -Gul

Patryk Zawadzki

unread,
Nov 26, 2007, 8:30:32 AM11/26/07
to django-d...@googlegroups.com
2007/11/26, David Ross @ Wolfeon <david...@wolfeon.com>:

>
> I can be unclear at times, especially while I'm very tired. I'll have
> to make an example of what I'm talking about included with an example
> or so. People tend to be a bit more understanding if there is
> something there to play with instead of an idea.
>
> I try not to use by IP due to the problem you specified.
>
> The way I think of the second cookie, is more like a 2nd password.
> Sure, there is a possibility of a brute force with it to, but it is
> less likely they'll brute force a 2nd session id key along with the
> first. I see this security method implemented with login mechanisms as
> well. Of course, login mechanisms are a bit easier to secure, after
> the 5th try, banned. ;)

I'm not sure what makes you believe that two cookies are more secure
than one. Two n-bit strings are just as secure as one 2n-bit so a
simple answer would be: make the session ID twice as long.

Also, if you are securing an administration panel, write a custom
middleware or even better a view decorator that stores the IP in the
session and clears the session if the IP changes.

A trivial thing to do and you are free to only apply it to views where
it actually makes sense (so regular users can switch IPs as much as
they want while admins get logged out if their IP changes).

If you need strong security, use SSL combined with signed client
certificates to authenticate (again, even SSL certificates can be
bruteforced if you throw enough computing power at them).

--
Patryk Zawadzki
PLD Linux Distribution

Marty Alchin

unread,
Nov 26, 2007, 8:46:55 AM11/26/07
to django-d...@googlegroups.com
On Nov 26, 2007 7:47 AM, David Ross @ Wolfeon <david...@wolfeon.com> wrote:
> I try not to use by IP due to the problem you specified.

Glad to hear it.

> The way I think of the second cookie, is more like a 2nd password.
> Sure, there is a possibility of a brute force with it to, but it is
> less likely they'll brute force a 2nd session id key along with the
> first.

Less likely, yes, but still possible. If you're really just concerned
with likelihood and probability, as opposed to pure security, I think
you'll find the track record of Django's session framework quite
suitable for most needs. And if you need to lower the probability of
exploitation even further, feel free to apply the signedcookies
middleware. It's easy.

> What would be interesting is to modify the session framework to "ban"
> an ip once it has made several Suspicious attempts. What is the point
> of raising a Suspicious exception if it does nothing?

But what's the point of banning an IP if you yourself admit that it's
not a reliable way to identify someone? Of course, writing something
like that would be quite easy to implement in a custom middleware. In
fact, you'd be able to have it catch any SuspciousOperation exceptions
for any request,[1] which would allow it to function on sessions,
signed cookies, or anything else that raises that exception.

Just have it cache a dictionary, mapping IPs to the number of
SuspiciousOperations, and automatically return HTTP 403 for any IP
with a number higher than whatever limit you like. It'd be fairly
straightforward, just make sure to store it in a proper cache, rather
than a module-level dictionary, since those are unique per-process,
and subsequent requests are likely to be served from different
processes.

-Gul

[1] http://www.djangoproject.com/documentation/middleware/#process-exception

Marty Alchin

unread,
Nov 26, 2007, 8:48:48 AM11/26/07
to django-d...@googlegroups.com
On Nov 26, 2007 8:30 AM, Patryk Zawadzki <pat...@gmail.com> wrote:
> I'm not sure what makes you believe that two cookies are more secure
> than one. Two n-bit strings are just as secure as one 2n-bit so a
> simple answer would be: make the session ID twice as long.

And that's exactly what the signed cookies middleware would do, if you
applied it to the sessions framework.

-Gul

David Ross @ Wolfeon

unread,
Nov 26, 2007, 1:57:29 PM11/26/07
to Django developers
What is the license for the signed cookie code?

Marty Alchin

unread,
Nov 26, 2007, 2:38:34 PM11/26/07
to django-d...@googlegroups.com
As stated on the code page[1], it uses the New BSD License, though I
really should include that in the source itself.

-Gul

[1] http://code.google.com/p/django-signedcookies/

Luke Plant

unread,
Nov 26, 2007, 4:36:15 PM11/26/07
to django-d...@googlegroups.com
On Monday 26 November 2007 12:17:51 Ned Batchelder wrote:

> In any case, if the signedcookies code makes you feel better about
> the security of your site, you should certainly use it. There's no
> point in being "disgusted" at Django as a whole.

Agreed - to put it mildly! Django uses a 128 bit session key -- 32
hexadecimal characters. The computational power just to cycle through
these values is vast: Wikipedia: "one would need a device consuming at
a minimum 10 gigawatts (about the equivalent of eight large, dedicated
nuclear reactors) running continuously for 100 years."

But the time argument is even stronger -- since you are talking about a
session key for a web app, the *only* way to check if you have the
right key is to attempt to access a restricted page, which is going to
take a significant fraction of a second (say 0.10 sec for a typical
Django request). Do the sums, and you're gonna need 10^30 years to
brute force that. (Yep, that's a thousand billion billion billion
years).

Luke

--
"Making it up? Why should I want to make anything up? Life's bad enough
as it is without wanting to invent any more of it." (Marvin the
paranoid android)

Luke Plant || http://lukeplant.me.uk/

David Ross @ Wolfeon

unread,
Nov 27, 2007, 12:55:27 AM11/27/07
to Django developers
On Nov 26, 3:37 am, "Marty Alchin" <gulop...@gamemusic.org> wrote:
>If you're as concerned with security as it
> sounds like you are, you might look at SecurID.[1]
>
> -Gul
>
> [1]http://en.wikipedia.org/wiki/SecurID

After thinking about it for a while, perhaps using SecurID would be
the better solution in such situations. Some think I'm a bit zealous
with security, and I've the reason to be. ;) I don't ever want to be
the person which everyone says, "look at that guy, he was the one at
fault for the break-in at <company here>"

David Ross

Ian Holsman

unread,
Nov 27, 2007, 8:05:11 PM11/27/07
to django-d...@googlegroups.com
David Ross @ Wolfeon wrote:
> After thinking about it for a while, perhaps using SecurID would be
> the better solution in such situations. Some think I'm a bit zealous
> with security, and I've the reason to be. ;) I don't ever want to be
> the person which everyone says, "look at that guy, he was the one at
> fault for the break-in at <company here>"
>
>
That why large companies have comittee's and auditors for.
> David Ross
> >
>
>

David Ross @ Wolfeon

unread,
Nov 28, 2007, 6:26:09 AM11/28/07
to Django developers
On Nov 27, 4:05 pm, Ian Holsman <kry...@gmail.com> wrote:
>
> That why large companies have comittee's and auditors for.
>

Oh yes, I learned what a committee was for when I walked on to a job
which was a complete mess. Make it look like I was at fault, when they
were just buying cheap hardware from Dell. Dell is on my blacklist for
not supporting budget servers when companies like Supermicro, better
than Dell, still support a great deal of their hardware which is
older. I never had to deal with a committee before then, only because
I never dealt with cheap or went cheap. Was even better when the cheap
Iomega NAS went down, and the Solutions CD was nowhere to be found.
Hooray for another cheap product which only has software raid. *sigh*

The Scarred System Administrator,
David Ross
Reply all
Reply to author
Forward
0 new messages