On a recent pentest, I reported that the session management cookie was not being set with the
secure flag (surprise, surprise)…
But in this case it didn’t seem to matter so much. Why? Because port 80 was shut: the whole application was served over HTTPS so the cookie would never have the chance to escape over HTTP, even if an attacker could engineer such a scenario – for example, by enticing the victim to click on a HTTP link (although more on this shortly). This is because the TCP connection must be set up with the 3-way handshake before any application data is sent over it – and since the port was closed, the connection falls at the first hurdle .
Nevertheless I still reported the missing
secure flag because the application was in a test environment and what if port 80 was open on the live server? Now the cookie is more vulnerable. And there’s another consideration. While port 80 on the host under scrutiny (e.g. secure.example.com) was filtered, port 80 may have been open on another related host (e.g. test.secure.example.com or www.example.com). If the attacker used a HTTP link to another such host instead, then when the link was clicked, the cookie could be transmitted. You’ll notice a “could” there – it depends on any accompanying
path restrictions on the cookie when it was set (and possibly how the browser interprets them).
The classic protocol-host-port tuple of the Same Origin Policy (SOP) doesn’t apply to the scoping of cookies. If it was, we wouldn’t need the
secure flag because, assuming the cookie was set as
secure over HTTPS, the request over HTTP would be a change of protocol and port, so it wouldn’t be transmitted. Cookie security pre-dates SOP as we know it (or sort of know it!) and its definition of “same origin” is different. I recommend Michal Zalewski’s Browser Security Handbook or his book The Tangled Web for more details, then fire up your web proxy and experiment! And it was while doing just this that I discovered another side to the
For the same reason, the
secure but not
secure cookie, it could overwrite the cookie – what’s known as “clobbering”.)
Incidentally, Internet Explorer 10 seems to have corrected the bug noted in the Browser Security Handbook:
There is no way to limit cookies to a single DNS name only, other than by not specifying
domain= value at all – and even this does not work in Microsoft Internet Explorer…
It appears this statement covered IE versions 6, 7 and 8. Well, I can’t speak for 9 but with IE10 I noticed that a cookie from foo.example.com with no
domain attribute wasn’t later sent to example.com.
To finish off, remember that you can only set the
secure flag if the application is designed with this in mind since any HTTP request will be missing cookies that have been set as
secure. An obvious side effect of this, for example, could be that the newly authenticated session management cookie set over HTTPS is withheld over HTTP, effectively logging off the user. Of course, whether or not the application should revert to HTTP following secure authentication is another matter!
===== UPDATE =====
 Dafydd Stuttard, aka PortSwigger, pointed out a neat bypass using the link http://www.example.com:443. Now the TCP connection succeeds and the browser sends the HTTP request. The SSL connection will of course fail but it’s too late, the session management cookie has gone up in the plain text request. (This is why he wrote the Web Application Hacker’s Handbook and I didn’t.) He also noted that since the attacker is in a position to sniff, having seen the SYN to port 80, the SYN/ACK could be spoofed in order to trick the browser into thinking the port is open. Thinking about this further, in an open Wi-Fi network the attacker could do this without even being an active man-in-the-middle using the Airpwn principle.