View All Articles or articles on Technology

Is your usage of HTTPS actually secure?

The answer is probably no.

I have seen over the years many people suggest (and implement) that anywhere you're taking client's data you should use a secure page (ie. HTTPS) and not HTTP. This is fine, but then what? What about when the user is not transferring their data such as login etc? There's a 90% chance that you're switching straight back over to HTTP, but sharing the same session across protocols.

The problem

The problem here is nothing to do with the data that is being transferred, but more about general security of your web application. If you're authenticating on HTTPS, you're entering data into a secure session, that is, once you've logged in the session ID will be transferred over a secure connection and sniffers won't be able to see what's going on.

Here comes the problem, generally once you've logged in, people switch right back over to HTTP.

The session ID which you've just populated (server side) is now being transferred unencrypted, back to the client. If the client's on an unsecure network, or has spyware/malware installed on their system, that's it, anybody can take over their session and browse their website.

False sense of security

HTTPS is never really thought about. Most people I know think that as long as forms and sensitive data is transferred is HTTPs everything is fine and dandy. This is generally true, unless you're persisting the state over HTTP aswell. This too, goes for cookies.

If you set a cookie via HTTPS, it's still going to be there on HTTP, so you best be damn sure that whatever you're setting is not sensitive. Luckily for you, there are a couple of ways to attempt to circumvent this, short of rewriting your application.

Possible Fixes

When it comes to sessions and cookies, by default they are setup in a pretty unsecure way. This means that they generally work on any domain underneath your site's primary domain, they're available to Javascript, and they're sent over insecure connections.

You are infact able to let the browser know of these 2 things: Don't send the cookie over an insecure connection, and perhaps most importantly (for compromised web pages) don't let the cookie be accessed via client-side scripting, only over the subsequent HTTP requests.

Securing PHP Sessions - There are 2 variables that you can set in your php.ini to make your sessions more secure. Stick this at the bottom of your php.ini and you will gain instant security. Note that your application may be affected as cookies are no longer available on both HTTP/HTTPS..

session.cookie_secure = 1 session.cookie_httponly = 1

Securing PHP Cookies - In the same way as before, you will simply amend your line of code that sets the cookie by adding 2 parameters to the end of your call, this means that any instances of this:

setcookie("YourCookie", "Your Value", time() + 3600, "/", "");

.. should be changed to this, thus providing the extra two parameters secure and httponly (the same as what's used by your session cookies):

setcookie("YourCookie", "Your Value", time() + 3600, "/", "", true, true);

These fixes are not only extremely simple to implement, but you're helping to secure yourself against several methods of session hijacking, the most important perhaps being XSS attacks and network sniffing.

Anything else to be done?

There's lots more to be done. No web application is 100% secure by design and pretty much everything has flaws no matter how much it is thought about, we don't live in a perfect world.

To prevent hijacking on a high level (this is more security through obscurity than anything), you could implement your own session handler which does some more extensive checking above simply matching a session ID. The best variables you can use before re-initialising the sessions data would be the client's IP Address, User Agent, and perhaps even setting another cookie as a sort of "Session Security" cookie.

What I mean by a "Session Security" cookie is that your session will only re-initialise if that cookie is present in addition to the session cookie (generally PHPSESSID).

If anything's unclear, feel free to hit me up in comments ;-)