Opened 12 years ago

Closed 11 years ago

Last modified 10 years ago

#362 closed defect (fixed)

Anonymous sessions should try to prevent session-stealing

Reported by: jmcbray-django@… Owned by: Adrian Holovaty
Component: Core (Other) Version:
Severity: normal Keywords: sessions, security, authentication
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


If a user can sniff (or guess) a session id, they can take over a user's session.

The simpler types of attempts to steal sessions can be prevented by gathering as much information as possible about the client when creating a session, and then verifying that that information hasn't changed on subsequent requests. If it has, it should log a warning and log the user out. A hash of REMOTE_ADDR and, if it exists, PROXY_FORWARDED_FOR is commonly used to prevent replay attacks like this.

This is easy enough to implement in the application, but it should probably be built into the framework. A way of providing page tokens/nonces would also be useful, and this could be used to avoid sending session tokens to the client entirely.

Though this technically an RFE, I'm submitting it as severity normal, because the easiest way to do sessions should be secure by default.

Change History (8)

comment:1 Changed 12 years ago by Simon Willison

I've always been a little wary of systems that tie sessions to an IP address - for one thing, many people are on shared IPs (behind NAT) and if someone has sniffed a cookie there's a good chance that they are on the same network, and hence share the same forward facing IP anyway. I've also heard stories of some ISPs that rotate the IP address used quite frequently (does AOL do this?) hence invalidating the session.

PROXY_FORWARDED_FOR could help with both of these problems, but how well supported is it?

I'd like to hear about prior art - how do other widely used frameworks (.NET, PHP, Rails etc) implement session security?

comment:2 Changed 12 years ago by Adrian Holovaty

Yes, AOL rotates IP addresses, so it's not safe to assume a user will have the same IP address across his session.

comment:3 Changed 12 years ago by hugo <gb@…>

tying sessions to IP addresses will break if users use privacy enhancing systems like JAP or tor - they usually come with many different addresses. Other situations where you have changing IPs are load balanced proxy clusters that might fetch pages with multiple addresses, changing them in some round-robin fashion.

comment:4 Changed 12 years ago by Adrian Holovaty

PHP uses the same level of security Django uses -- it relies on a secret session ID in a cookie. Here are a few good articles:

The only real solution those articles present is to hash the USER_AGENT in the creation of the session ID, and compare that on each request. Although IP addresses change, it could be safe to assume a user-agent won't change. Granted, many people use Internet Explorer, so it could be easy for an attacker to guess Internet Explorer, and there's some wonky Firefox Extension that changes the user-agent on each request -- but hashing the user-agent still might be a good solution.

comment:5 Changed 12 years ago by Adrian Holovaty

Note that PHP also allows session IDs to be passed in GET parameters. That's a pretty substantial security problem, in my view, because session IDs get displayed in referer logs and bookmarks and other places. It's intentional that Django doesn't do that.

comment:6 Changed 12 years ago by Adrian Holovaty

In [536], I improved the session code to force creation of a new session key if the given session key doesn't exist -- based on a tip from the above documents.

comment:7 Changed 12 years ago by jmcbray-django@…

When I posted this, I was aware of the problem with tying sessions to IP addresses, but it's the easiest-to-implement solution to the problem. Using USER_AGENT or other client-provided header as an identifier is not very useful unless it is combined with information about the client they can't forge, but it is probably better than nothing. Hashing several optional headers (if they were provided in the initial request), as suggested here: might help a little, too.

The solution using page-specific tokens or nonces would be better (essentially, session-ids as visible to the client cannot be re-used), but harder to implement. There's a thorough discussion of the issues in the guide found at; skip forward to the chapter on session management.

I wonder if it would make sense to have a separate "paranoid_sessions" middleware from the standard sessions middleware that would increase security at the cost of interoperability with the degenerate cases mentioned above.

comment:8 Changed 11 years ago by Adrian Holovaty

Resolution: fixed
Status: newclosed

This is fixed for now -- see [536]. If people are interested in "paranoid" sessions, feel free to open another ticket.

Note: See TracTickets for help on using tickets.
Back to Top