0

I am making a mobile game with JQuery Mobile, a multipage template (so all pages in 1 html file, which makes it usable with PhoneGap).

Since it is HTML I am using JQuerys $.post function to send data to php scripts such as login.php, register.php, which add/update/delete data from the MySQL db.

When I $.post to login.php, upon authentication I return the users ID, then encrypt it client side using CryptoJS AES, store it in HTML5's localStorage, and when I need to make requests to protected pages, send this encrypted userID, decrypt it server side, and execute the MySQL commands assuming the user is authenticated.

The problem with this, is unlike cookies, localStorage variables can persist for long periods of time, which I believe would make my app potentially vulnerable to session hijacking if XSS could be executed.

I would like to keep things as secure as possible on behalf of my users, can someone tell me how to properly implement a safeguard against the session hijacking weakness of what I described?

dario
  • 5,149
  • 12
  • 28
  • 32
JohnWick
  • 4,929
  • 9
  • 37
  • 74
  • Are you looking for [`sessionstorage`](http://www.nczonline.net/blog/2009/07/21/introduction-to-sessionstorage/)? – Scott Arciszewski Jun 16 '15 at 16:08
  • Does sessionStorage handle expiration of data like cookies? I know sessionStorage is purged when the browser is closed, I would like the data to persist. I have decided to just use the $_SESSION variable, which works really well, but I believe the user will have log back in everytime they close the app/browser, unlike a cookie. Is that correct? – JohnWick Jun 17 '15 at 02:38
  • Any reason to encrypt? Why not sign a token containing the user ID, and an expiry date with a [HMAC](https://en.wikipedia.org/wiki/Hash-based_message_authentication_code) using a server-side secret key? You simply reject any tokens when the expiry date has elapsed. – SilverlightFox Jun 17 '15 at 09:23

1 Answers1

1

The usual php session_start() method is fine to use over HTTPS, and I think it is best solution for you. Let the server handle the session for you. As SilverlightFox has pointed out, it's a good idea to use http only session cookies. Before you start your session use session_set_cookie_params like this.

//10 minute session, forces https only and attempts to set the httponly flag
session_set_cookie_params(600, '/', '.domain.com', true, true);
session_start();

You should also take a look at Token based authentication as it covers "Access Control" as well.

Note: To prevent "man in the middle" attacks, both methods require that any cookies/tokens are sent/received over HTTPS.

This is a common problem with web apps. I really recommend this blog article as it explains the issue in more depth. But I also must point out some major security holes in your approach.

Firstly, doing any kind of encryption on the client side is considered insecure due to the fact that the client must deal with the "sensitive" plaintext data before encryption. Anyone can look at the client side code and see whats going on.

Additionally, an attacker would probably be able to work out how to encrypt (and hence spoof) any id they want, since the shared AES key would need to be made available to the client encryption code.

HTML5 localStorage/sessionStorage is just a datastore which can persist across requests. Since the browser wont be navigating anyway, you wont get any benefit over a normal javascript variable (apart from maybe being able to reload state if a user does decide to refresh/reset). It has no real use when it comes to authentication.

Phil
  • 1,996
  • 1
  • 19
  • 26
  • Awesome response, I actually just went with using php session_start and storing the users UID unencrypted in the $_SESSION variable. Also good point about encrypting client side, I know that was dumb so not sure why I was even testing it...I suppose if it was decrypted serverside with a private key this would be ok though? – JohnWick Jun 17 '15 at 02:36
  • Yep, no need to encrypt serverside session really unless you consider your server insecure. By using https your php session cookie is essentially decrypted with a private key. One last thing is to use httponly cookies. I thought php used httponly by default but it doesn't http://stackoverflow.com/questions/36877/how-do-you-set-up-use-httponly-cookies-in-php – Phil Jun 17 '15 at 06:53
  • Using HTTPS doesn't make your application secure against XSS. It also doesn't make the session cookie decrypt with a private key. Yes it does encrypt the session cookie while it is transit, but an XSS attack still may be able to retrieve it. – SilverlightFox Jun 17 '15 at 09:26
  • @SilverlightFox Thanks. Yes I realise that this is not default php behaviour. I will add a code example to my answer for turning on http only session cookies. The S in HTTPS stands for SSL which negotiates an encryption tunnel by a key exchange mechanism using public/private key. What I meant to say was that Davids suggestion to use public key cryptography at the application layer would give no increase in communicational security if he uses SSL at the transport layer anyway. – Phil Jun 17 '15 at 11:04