[Mapbender-dev] Tying IP addresses to Sessions
Karim Malhas
karim at malhas.de
Mon Oct 19 18:20:47 EDT 2009
Dear List,
When writing this, it got rather long, so I figured I would put a
summary at the top:
--
In this weeks IRC meeting we very briefly discussed that mapbender ties
a php session to the client IP address. And that this behaviour
causes some problems.
Associating Sessions to IP addresses is not really a security feature ad
creates problems by mixing HTTP with IP.
We should drop it.
--
The idea behind it is that if a client's IPaddress changes within a
session, this must mean the sessionID was stolen and the Session
must be closed
This forces the stateless HTTP protocol to respect some kind of ad hoc
idea of a session, which creates these problems:
- One of the advantages HTTP is, that data can be cached. This is done
via proxyservers. If a client makes a request through a proxyserver
the server sees the IP address of the proxy, not the client.
So if a client uses more than one proxy in one session, he
invalidates his session, because it's ip address changed.
- Another problem involving proxies and Sessions which is not migitated
by tying IP addess and SessionID together, is that an attacker behind the
same proxy as the User can still steal a Session, because he has the
same IP address
- The same is true for any other kind of proxy, say, a socks proxy, or
someone connecting via tor[1]
- There are some other reasons why an IP address might change between each
HTTP connection.
We are really trying to protect a Ressource on a server from
unauthorized access.
So whom are we trying to protect it from?
- Anyone who is between the Webbrowser and Our Server
If we assume that a proxy or a NAT device is involved, we can
differentiate between two kinds of attackers:
Outsider Attackers: between the Server and the Proxy/NAT
This is where the tuple of SessionID and IPaddress helps a little
Inside Attackers: between the Client and the Proxy/NAT
Here SessionID,IPaddress do not help create security, because the
attacker has the same IP address as the User
(There are other attacks, but they are not in focus here)
So here's how we can try to prevent an attack, without usinng the
IPaddress check:
Right now we want to protect a ressource on the server by having
a user log in once, and then keep sending some kind of
token to prove, that she is the same user that logged in at the
beginning.
We therefore need this token to be protected from unauthorized use by an
attacker.
Some definitions:
C A HTTP client sending data to Server.
S A HTTP Server sending data to Client
User The client we want to grant access to a ressource
Attacker The client we want to prevent from accessing a ressource
We assume that an attacker can read all the communication between the
Client and the Server (it is after all, the attacker)
1) This is the normal case:
Client authenticates, and receives SessionID:
1.1 C: GET /login HTTP/1.1
Host: example.com
Authorization: Basic eW91c286c25lYWt5
1.2 S: HTTP/1.1 200 OK
Cookie: SessionID=blafasel_1
<additional headers and data>
1.a Attacker steals SessionID here
Client sends Same SessionID for each requested Ressource
1.3 C: GET /secret HTTP/1.1
Host: example.com
Cookie: SessionID=blafasel_1
1.4 S: HTTP/1.1 200 OK
<headers and data>
Client or attacker send next request
1.5 C: GET /ohsoverysecret HTTP/1.1
Host: example.com
Cookie: SessionID=blafasel_1
1.6 S: HTTP/1.1 20O OK
<headers and data>
After 1.a the server can't be sure wether requests come from the same
client that authenticated in 1.1 because now two clients could know the
sessionID
We introduce a SessionID, that is not constant over a Session but
changes with each request (like for example the php function
session_regenerate_id)
Client authenticates, and receives SessionID:
2.1 C: GET /login HTTP/1.1
Host: example.com
Authorization: Basic eW91c286c25lYWt5
2.2 S: HTTP/1.1 200 OK
Cookie: SessionID=blafasel_1
<additional headers and data>
Client sends Request with SessionID, Sever answers with data and
new SessionId
2.3 C: GET /secret HTTP/1.1
Host: example.com
Cookie: SessionID=blafasel_1
2.a Attacker steals SessionID here
2.4 S: HTTP/1.1 20O OK
Cookie: SessionID=blafasel_RANDOM5678
<additional headers and data>
2.b Attacker steals SessionID here
Client sends next Request
2.5 C: GET /ohsoverysecret HTTP/1.1
Host: example.com
Cookie: SessionID=blafasel_RANDOM5648
2.6 S: HTTP/1.1 200 OK
Cookie: SessionId=blafasel_RANDOM1234
<additional headers and data>
The SessionID stolen at 2.a is now useless to the attacker, because it
is only good for one single request
If the attacker steals it at 2.b however he can use it to to generate a
valid request if he can do it faster the the User. If he does that, he
will receive the next valid SessionID and the User will not,
effectively locking the User out of his own session.
If we continue like this we could try to come up with some kind of
scheme that makes the SessionID a kind of cryptographic Token,
but this squeezes the SessionID into a function it was not really
supposed to have, and maybe impossible to do, because the client can't
really do any calculations on it which might be neccessary.
oooor we could use one of the following already existing ideas to this
problem:
- use HTTPS: Best Idea of course when accessing protected ressources
- HTTP Digest authentication:
If you noticed, I used Basic auth in my example, this of course a
bad idea if not using HTTPS
Digest authentication solves our problem by using a cryptographically
sound token to authenticate the User in each request
The following is a pretty good summary of how this could be done:
http://www.peej.co.uk/articles/http-auth-with-html-forms.html
As a last remark: If we assume that an attacker can read all our
communication (which is the assumption behind tying SessionID and
IPaddress), then we don't even have to go through all this trouble,
because right now, the login form sends our password in the clear
anyway and an attacker does not need to highjack a session.
she can just use the password to create a new one.
thx for reading this far,
Karim
More information about the Mapbender_dev
mailing list