0

I am building an e-commerce website using PHP, mysql, javascript.

My idea is to save one token, say a 50 character guid, to a single cookie, and use this to identify the user for each request.

I would then save other items such as cart_id, order_id, customer_id, logged_in (bool) and expires_at in a sessions table of the database.

I would probably then refresh the token upon each corresponding request and renew it's expiry time.

I'd like to know if this would be considered a secure way of maintaining a session, and if it's generally a good idea.

Also, anything else I can do to make a logged in session more secure would be a bonus. Thanks.

Edit:

This is the function I'm using to generate my guid:

<?php
function guid($length) {
    $bytes = ceil($length/2);
    $guid = bin2hex(openssl_random_pseudo_bytes($bytes));
    return $guid;
}

I'm calling it as follows:

<?php
$token = guid(50);
Marc
  • 141
  • 1
  • 6
  • Are you using any frameworks? Laravel, Lumen, Silex, etc? I would use the framework provided session management mechanisms. – Daniel Szpisjak Aug 03 '17 at 15:40
  • Sorry, no, not using any frameworks. It's my own bespoke cms built with vanilla php. – Marc Aug 03 '17 at 21:48
  • At first glance this looks correct however I strongly recommend you to use mature frameworks to do this - chances are that a mistake will slip in and make your implementation vulnerable. If this is for a serious website (versus playing around), you should really avoid reinventing the wheel, which is what you are doing here :) – niilzon Aug 04 '17 at 08:18
  • OK, thanks for the suggestion. What framework is generally considered the best right now? Laravel would you say? – Marc Aug 07 '17 at 15:14

3 Answers3

1

Do not use a GUID as a session identifier, GUIDs may be cryptographically secure, but they are not always. Since you're using PHP you should use PHP's default session cookie implementation since it uses a CSPRNG (as of 7.1, for older versions see here).

Session hijacking can be avoided by:

  1. Using a CSPRNG to avoid predictable session identifiers
  2. Set the Secure flag on the cookie to avoid sending it over an unencrypted connection
  3. Set the HttpOnly flag on the cookie to prevent javascript from reading it

Recent versions of PHP do #1 for you, and session_set_cookie_params allows you to do #2 and #3.

Related: Are GUIDs safe for one-time tokens?

AndrolGenhald
  • 15,506
  • 5
  • 45
  • 50
  • Perhaps I implied by the wording of my question that I was using php's built in guid function. I've now edited my question to include the function I use to generate the token. I was under the impression that this function could generate high entropy random strings. Does your answer still apply, or does this change anything? – Marc Aug 03 '17 at 21:46
  • I don't see anything wrong with it, it looks like it should be 200 bits of entropy, but I would still hesitate just due to the language. GUID doesn't imply unpredictable, what if someone comes along in a few years and changes how GUIDs are generated? I also wouldn't trust myself to implement something like this without it going through a lot of review. Is there any particular reason you want to avoid the built in session management? – AndrolGenhald Aug 03 '17 at 21:55
  • The main reason was because I intended for this cookie to have an expiry date of longer than an average session, so that if say the user returned to the site a week later, their basket would still be intact, and the site would remember who they were. – Marc Aug 03 '17 at 22:06
1

Yes, GUIDs are good for one part of session management. Basically all that it gives you is a unique, collision-less string guaranteed to be unique, that's all. However your entire session management is more than that. Some requirements for session management if you want to roll your own: because the GUID looks garbled, it does not meant that it is encrypted.

  1. Unique session identifier (your GUID fulfills this requirement).
  2. Session expiration and recovery.
  3. cookie poisoning prevention.
  4. Authenticated and authentication-less binding. check some of the PHP frameworks how they do it, you can start with wordpress, that is probably the simplest. You can actually borrow their approach and code parts in your implementation (they are mostly open source).
Anders
  • 65,052
  • 24
  • 180
  • 218
Hugo R
  • 177
  • 2
0

Persistent tokens are vulnerable to the infamous "my kid did it" attack. It's okay to keep the cart that way but you should force reauthenticatipn (with a temporary session cookie that drops when the browser is closed) for actual point of sale.

John Wu
  • 9,181
  • 1
  • 29
  • 39