I know many of you are in the web development and security arenas… I figured I’d throw this idea up for everyone to have a look at.
Authenticating users on a website can be quite a challenge at times. Sometimes, HTTP Basic authentication is all that’s required, re-sending the password with each request. But the problem with this; is that someone can intercept the username and password, thus knows everything needed to establish a new session.
HTTP Digest authentication is good; but MD5 isn’t as strong as other hashing algorithms available, and more importantly, it assumes the server knows the exact password. But what if you’re hashing the password? Also, this doesn’t necessarily solve the issue of session hijacking.
Thus what I have come up with, is “Challenge-Response Digest Authentication”. My rationale for this method of authentication and session management is as follows:
- Remove the need for the cleartext password to be stored or transmitted. Using CRDA, only the hash of the password needs to be stored.
- The remote user still needs to demonstrate knowledge of the password (or rather, its hash)
- Various aspects of the client, such as the IP address and user agent, are used when generating the hash, making session hijacking more difficult.
- Remote client makes a request to log in by requesting the login form.
- The server generates a session ID, which is the hash of the following (in this order):
- IP Address of client (from the server’s perspective)
- Client User Agent
- A random salt string
- IP Address of client
- User Agent in use
- The random salt given
- The username
- The hash of the password
The cookie generated earlier is passed back to the server as well so it can look up the salt value.
- The server receives the session ID (via cookie) as well as the username and response (via HTTP POST), looks up the salt for that session ID, then checks the following:
- The session ID is valid for the given IP and user agent
- The response is valid
If successful, the server generates a random nonce value, and passes this back to the client. The session key to be used from this point forward, is the hash of the following information:
- IP Address
- User Agent
- Random Salt
- Nonce value
The nonce is then updated at regular intervals. On an intelligent client, the raw nonce value could be passed back right at the start, and stored — the client incrementing it when told by the server. On a simpler client, the key may get passed back and forward.
For each request after this initial authentication step, a cookie should be passed to the server containing the following string: “SessionID:SessionKey”.
Anyways… those are my ideas. I know there are problems with this; most notably, is the effectiveness of hashing when you hash something twice. I know that SHA1 is less effective in this instance — but the question is, how much less effective? I figure it’s not really enough to be worried about, but then again, I know there are people who work in this field, and thus will know more about it than me.
I’m still tinkering at this stage, I’ve got a small proof-of-concept webapp going that utilises this scheme at a basic level, and I’ll keep poking at it for now, but I’d be interested in hearing other people’s thoughts on whether this would be effective against preventing session hijacking and keeping a site secure.