0

I've seen a PHP security tutorial where it says never to accept $_SESSION identifiers from GET or POST variables due to session hijacking and fixation. It annoyingly doesn't go into any real detail on this though.

In an application I'm building I have a $_SESSION value that is the $username variable that is set when a user logs in. This value is taken from the database, but is later used in GET requests via URL parameters:

$_SESSION['username'] = $username;

Note: The $username and all other data is sanitized going into the database and escaped when being fetched from the database.

Is the above session name a real no-no? And if this is indeed bad practice should I be using the user id from the database or similar information that is never publicly displayed (e.g. in a url parameter)?

Using the $username variable is handy because I use it in url parameters as well via the $_SESSION value, an example of which is below:

<a href='<?php echo "profile.php?username={$_SESSION['username']}"; ?>'>My Profile</a>

When a user logs in the actual session id is regenerated with session_regenerate_id(true); so the id of each session changes each time the user is authenticated.

Any advice would be greatly appreciated.

pjk_ok
  • 618
  • 7
  • 35
  • 90
  • 1
    If you're using `username=` in your URLs then the client can put whatever they want in there. This is likely a security issue. (Except perhaps in the case of a profile page where it's public anyway.) In general, you create the session after authentication, and then any time you need to know who the currently-logged-in user is, you just pull it out of the session at the time you need it -- i.e., use `$_SESSION['username']` _inside_ the profile.php script, not as a parameter to it. – Alex Howansky Jun 04 '21 at 01:39
  • Hi @AlexHowansky, I should add that I have a condition where if I use the GET request for a url parameter it does have to match the session before any database changes can be made i.e. `isset($_GET['username']) ? $username = $_GET['username'] : header("Location: index.php"); // exit if not logged in user if($_SESSION['username'] !== $username) { header("Location: index.php"); exit; }` – pjk_ok Jun 04 '21 at 01:48
  • Why bother? The extra check is unnecessary. Just take username out of the session and you're done. (Assuming you created the session after authentication.) – Alex Howansky Jun 04 '21 at 02:18
  • @AlexHowansky I'm really confused. So what should I use to authenticate the user session on login? Should I pull the user id from the database and use that? And then whenever the user makes changes to the database make sure the loggedin/authetication session matches the database record for that user id? – pjk_ok Jun 04 '21 at 02:57
  • 1
    I'm assuming you're taking user/pass from a form POST, checking against the db, and then putting `username` in the session only _after_ they've passed auth. If so, then `$_SESSION['username']` will be available in all that user's subsequent hits. You don't have to keep checking it against a GET parameter, you can just do this: `echo "You are " . $_SESSION['username'];`. Generally the only time username should be passed in POST is on a login/reset page and the only time it should ever be passed in GET (or in the URL) is when you need to refer to a different user, like for a public profile page. – Alex Howansky Jun 04 '21 at 03:49
  • @AlexHowansky I'm going to delete this question and re-word it. This isn't making any sense to me. I'm just reading it as no you shouldn't set a session as the username unless you need the username as a session then you should do it. I would also love to know on login/auth what is the best practice to use as the unique session identifier if not the username? The user's id? A token? It's got to be something unique to the user surely? No need to reply as will break it down on a new question. – pjk_ok Jun 04 '21 at 17:48

0 Answers0