We need to design a secure web application. I would like to propose a session handling mechanism which does a challenge-response on every request, not only during login using a CRAM method.
The reason is to harden the web application against session hijacking (eg by CSRF) and replay or man-in-the-middle attacks.
Using a nonce is suggested in some places, but in our webapp it seems impractical, as asynchronous requests can go on, or the user could open new windows, hit the back button etc.
Idea: The client and the server have a shared secret (a previously established user password), every subsequent request does again a challenge/response based on that secret, e.g 'response = hash(challenge + hashedPassword)'. The server executes the request only if the response to the challenge matches. Much like during CRAM, but ongoing for every request.
The question: Is this a feasible idea? If so, it surely has been implemented or is even some standard? How would we use this in a java or php based webapp?
I find the OWASP cheat sheets are a good resource for such design decisions:
Your scheme sounds similar to the HTTP digest authentication without establishing any kind of session post authentication. Which is probably an improvement over HTTP Basic. And that is assuming both are over TLS!
I am not sure how feasible your scheme might be or how vulnerable to replay attacks or MITM it might be.
If it is an option you might consider the new <keygen>
html5 tag which can help establish a two way TLS session. This would be the most secure option..
The question really comes down to what you want to achieve. If you want to fight CSRF-Attacks, a secret token in addition to the session key is your way to go. However, changing the token in every request will cause problems - not only will the back-button kill the session, but as one webpage usually contains a lot of asynchronously and parallel loaded data (images, css, javascript, etc.), your approach will not enable any additional data to be loaded afterwards, as each additional request will change the required token, thus killing the session.
You may get around this by embedding all resources into the page via BASE64 and other tricks, but that will seriously hinder your possibilities and may have compatibility issues with some browsers.
So, in the end, your approach will not add much security, but will most likely create a whole set of potential problems for your customers. I'd stick to one secret token per session in the URL to fight CSRF and concentrate on securing against other attacks like XSS and user-friendly security measures like two-factor authentication with a smartphone or something similar. After all, the user is the #1 attack vector nowadays.
Update (2012-06-14)
The token will not fight XSS-attacks, but it will defend against basic CSRF-attacks (e.g. by implanting a bogus url call in an image). I've actually had a situation at work today, where I needed to secure a get-request against user modification and worked up some code. The code may be also usable to secure static, session-timeout form
- and link
-tokens (right your problem).
The idea is to have a server-secret, which is used to generate a hash/AuthToken over data to secure. If a rogue javascript would try to change any of the given data, the AuthToken would not match. In my specific problem, I have one server authenticating a user and have to send his information over to a third party (username, mailaddress, name, etc.). This GET-Request might be easily changed by any user after authentication, so I have to authenticate the GET-Request-Parameters. By rerunning the AuthenticationToken-Process, the third party can compare the resulting AuthTokens, thus validating the incoming data. Without the shared secret, it is (near-to) impossible to forge the data.
On your problem: Having a static token on GET and POST-requests (or a dynamic one like the project of mine) will protect you against simple CSRF-attacks via e.g. links in forums, which a user has to click to get attacked. As the link will never contain the correct token, your webpage is secure. However, if an attacker manages to load a javascript into the webpage via XSS, you're screwed and no technique in the world will help against it, as the javascript can scan the whole DOM-tree of the page to find an capture any tokens whatsoever.
So, it comes down to this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With