I'm writing a web app that already uses TLS encrypted connections (HTTPS), Secure; HttpOnly
session cookie, HMAC-SHA1 CSRF token, requires correct Referer
header to avoid Login CSRF and changes session id during login to avoid basic session fixation attacks.
However, I cannot use HSTS because the same domain needs to serve some HTTP content for historical reasons.
I'm failing to understand how to avoid MitM attack that accomplishes session fixation in practice:
- Attacker navigates to
https://example.com/login
and receives a new anonymoussession-id
cookie and corresponding HMAC-SHA1csrf-token
embedded in login form. - Attacker completes login and the server overwrites the
session-id
cookie for the new user id. - Attacker saves the value of
session-id
cookie. - Victim navigates to
example.com
using HTTP and the attacker initiates MitM attack that modifies the response to haveSet-Cookie: session-id=<value-from-attacker-session>
andLocation: https://example.com/whatever
. - Victim's browser now completes full TLS handshake with
example.com
and doesGET /whatever
withCookie: session-id=<value-from-attacker-session>
. In practice, this is a completion of session fixation attack because Victim is now running the session shared with the Attacker.
Granted, this is not an easy attack because it requires active MitM attack and the Victim needs to use initial HTTP connection to example.com
. In addition, this only allows for session fixation, not session hijacking.
- Is HSTS the only way to avoid this attack?
- Is there any way to avoid cookies set via HTTP connection being visible on HTTPS connection looking identical to
Secure; HttpOnly
cookies?
Update 2014-09-04
I'm assuming following claims are true:
- TLS connection is secure and the UA has a sane list of trusted CAs.
- End user is able to avoid
sslstrip
-like attacks where browser chrome contains incorrect URL. example.com
is not on the preloaded HSTS list.
The guard cookie suggested by Steffen Ullrich would fix the issue except for the fact that it cannot detect if attack is done during initial connection. Implementing guard cookie would still avoid attack switching the session on-the-fly. Currently MitM Attacker could overwrite the original Secure; HttpOnly
cookie called session-id
with a regular HTTP cookie any time in the future he can get the UA to access any HTTP URL for the same domain. (This can be pretty easy because the Attacker can redirect any HTTP connection from the same browser session.)
I'm still failing to see any way to really fix this without any assistance from UA. If UAs only had a way to tell which cookies have been set over TLS connection instead of plain old HTTP...
(As a side not I have to say that all the suggestions to detect sslstrip
-like attacks by server side like described in the answer linked by Steffern Ullrich seem vain because all suggestions require sending JavaScript files that do the detection and sslstrip
is strictly about MitM attacker able to modify files on the fly. As such, the Attacker can easily make any JavaScript detection to always return "ok".)
Related links: 1. Cookie forcing 2. Login CSRF