When browsers like IE 11, Firefox 26, Chrome 32 etc. receive a Cookie over an insecure (HTTP) connection which has the "Secure" attribute specified, they store the cookie and send it back once they do a request to the same server over a secure (HTTPS) connection.
While this probably accords with some specification (I guess Netscape Cookies), I wonder if this opens an additional security hole (Session Fixation) to SSL-secured sites.
Consider the following scenario:
A user (having a clean/malware-free client device) wants to access a website which has a username+password login, over a non-secure network (e.g. unencrypted WiFi hotspot) where an attacker can read and modify all data sent over that network. Let the DNS name of the website be www.example.com
.
The user knows that when this website asks him to enter a password, to always look if the browser's address bar contains the SSL lock icon before entering the password.
The website:
- provides access to all its pages and resources over SSL/TLS. That means once the user visits a page using https, every internal links on that page are https links so that they do not "downgrade" the connection from HTTPS to HTTP. Also it does not contain any mixed (HTTP/HTTPS) content.
- redirects the user from HTTP to HTTPS with a 301 status code if a user accesses one of its pages over HTTP.
- stores login information in a Session Cookie.
- ensures that all Cookies (including session cookie) sent to the client are only sent over a secure (HTTPS) connection, and that they always have set the "Secure" and "HttpOnly" attributes.
- only accepts session identifiers that have been generated by the site and have been sent from the client over a Cookie that has the "Secure" attribute set (the website doesn't accept session identifiers from URLs etc.)
- is secured against CSRF by setting a user-specific token on HTML forms that is checked by the server when the user submits a POST request.
- is secured against XSS by properly encoding all strings that are output as HTML.
- does not implement HSTS, or the user's browser does not support HSTS (like IE, Safari).
- does not change the Session Identifier (value of the Session Cookie) when the user logs in.
Now, imagine that the attacker runs a programm that intercepts all data sent over non-secure HTTP requests, and if these are HTML pages, insert a snipped that makes the browser send a HTTP request to www.example.com, like an invisible img or iframe tag:
<img src="http://www.example.com/" style="display: none;" />
The attacker then visits https://www.example.com/
by himself to obtain a session cookie generated by the server, and keeps browsing the site to keep the session alive.
He then also modifies HTTP requests from the user to www.example.com
to include the same session cookie in the HTTP response that the attacker just got from the server. The cookie has the "Secure" flag set.
Now, imagine the user visiting some regular HTTP sites which don't transfer sensitive data and therefore do not have SSL. This means the user's browser will receive the session cookie sent by the attacker on these requests.
Later, the user wents to https://www.example.com/
and wants to log in. He looks at the address bar to ensure that the SSL icon is displayed, and because it is, logs in with his password. However, because the attacker fixated the user's session by sending a cookie with a "Secure" attribute over an insecure HTTP request earlier, the attacker now has access to the user's session state.
Note, that if the website was changing the session identifier when the users logs in, the attacker wouldn't have access to the user's session state, but it would still be possible for the attacker to login as himself and send his session cookie to the user, overwriting previous session/login cookies, so that the user does actions (e.g. write sensitive mails etc.) on behalf of the attacker.
My impression of this browser's behavior is that it introduces an additional Session Fixation scenario as described above. The only way that I can see to prevent this is to change the session identifier on each request (for a HTML page).
Am I missing something here?
My view would be that if a browser would reject cookies that have the "Secure" attribute set but were sent over an insecure HTTP connection, the attacker would not have been able to:
- inject a session cookie in the user's browser having the "Secure" attribute set as the browser would reject it, and
- (EDIT: not applicable) inject a session cookie in the user's browser which does not have the "Secure" attribute set, as the website would ignore cookies without the "Secure" attribute.
This would remove the need for the particular website from changing the session identifier with each request.
EDIT: Ok, one thing that I missed is that browsers do not seem to send the "Secure" attribute on the Cookie header back to the server, so the server has no way to determine if this cookie was set to the client's browser with the "Secure" attribute.
But this would mean, even if browsers would reject cookies with the "Secure" flag on non-SSL connections, it would be possible for the attacker to set a cookie without the "Secure" flag which then gets accepted by the website on HTTPS requests as it can't check the "Secure" flag of the cookie.
Any ideas?
Thanks!