Jump to content

secure login, strong(est) session ID's and secure site navigation


ajoo
Go to solution Solved by Jacques1,

Recommended Posts

Hi all !

 

I am really stuck on creating a secure login and site navigation system. Can someone say how secure sessions be created and how to use sessions / cookies / session - cookies together. for navigating a website, like moving from page to page and any special precautions to take while doing a critical task ( say one which involves accessing a database for reading or writing). Generally either sessions or cookies are used for this but I was wondering if it would be a good idea to use both in case that makes the system more secure. 

 

Thanks 

 

 

 

 

Link to comment
Share on other sites

I've used a session.php file that I coded that is bare minimum:

 

<?php
header("Cache-Control: no-cache");
  session_start();
  // If the session vars aren't set, try to set them with a cookie
  if (!isset($_SESSION['user_id'])) {
    if (isset($_COOKIE['user_id']) && isset($_COOKIE['username'])) {
      $_SESSION['user_id'] = $_COOKIE['user_id'];
      $_SESSION['username'] = $_COOKIE['username'];
} else {
header('Location: /login.php');
    }
  }
?>

Login:

 

I would then have a form that checks to see if the data exsist for the login and do the following:

          require_once('session.php');  // Start the session
     session_start();

  // Query database code goes here 
     $query = " "; // SELECT SOMETHING FROM USERS WHERE USERNAME = SOMETHING AND PASSWORD = SOMETHING
     $data = mysqli_query($dbc, $query);     if (mysqli_num_rows($data) == 1) {
           // The log-in is OK so set the user ID and username session vars (and cookies), and redirect to the home page
          $row = mysqli_fetch_array($data);
          $_SESSION['user_id'] = $row['id'];
          $_SESSION['username'] = $row['username'];
          setcookie('user_id', $row['id'], time() + (60 * 60 * 24 * 30));    // expires in 30 days
          setcookie('username', $row['username'], time() + (60 * 60 * 24 * 30));  // expires in 30 days
          $home_url = 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']) . '/index.php';
          header('Location: ' . $home_url);
    } else {
          // The username/password are incorrect so set an error message
          $error_msg = '<p class="error">Sorry, you must enter a valid username and password to log in.<br>';
        }
Each page the user would access would require an active session, using the session.php file. So if they didn't have a valid cookie anymore they would need to log back in, each login resets the session data.
 
Hope this helps you out.

 

Link to comment
Share on other sites

oh wow.

 

for security purposes DO NOT set cookies with things like user id's, usernames, passwords, or any sort of hashed versions of these, the main reason being is these values being stored in the cookies are fixed/static/unchanging for any one user and if anyone gets a hold of these values they can use them to impersonate the actual user until the values get changed.

 

if you need to identify a user longer than one browser session (i.e. session variables), generate a unique id (which is essentially what the session id is) and store that in a cookie and in the corresponding row in your user table. you would use this value to identify the user and since it is a generated value, not tied to any fixed information, it can be regenerated at any time.

Edited by mac_gyver
Link to comment
Share on other sites

No offense, Skewled, but WTF?

 

So you blindly accept any user ID people send you in a cookie? What if I create my own cookie with the user ID of the site admin? Does that make me an admin?

 

This is really, really wrong. Never trust the user input. This includes cookies, because anybody can create any cookie they want.

Link to comment
Share on other sites

No offense taken Jacques!

 

I was just showing how to create the session along with some cookie information, I should have certainly answered the OP question better so I am rather embarrassed  if anything lol. Use the code as an example for setting session variables and establishing cookies, and verification on pages that need to know if a session exists, don't use it verbatim.

Edited by Skewled
Link to comment
Share on other sites

 

 verification on pages that need to know if a session exists

 

and because the header() redirect doesn't have an exit; statement after it, the posted code won't prevent access to the protected page. the rest of the code on the protected page will run just the same and all anyone or a bot script would need to do is ignore the redirect to access the page and whatever the code on it permits.

Link to comment
Share on other sites

  • Solution

Instead of discussing the script above, maybe we should rather get back to the OP's question.

 

There are several things to take care of when dealing with sessions:

  1. It must not be possible to predict the session IDs. In other words, they have to be sufficiently random (which they're not by default).
  2. You must prevent the session ID from being stolen through JavaScript or in transit.
  3. An attacker must not be able to set the session ID of a victim (this is called session fixation).
  4. It's important to correctly terminate the session in the logout procedure.
  5. The lifetime of a session must have an absolute limit

 

 

 

1. Improving the session IDs

 

By default, PHP uses a very weak random number generator to create the session IDs. They're basically derived from the server time and some other trivial factors, which makes it relatively easy to predict them. If you google for it, you'll find plenty of tools for attackers.

 

To prevent this, it's very important that you use the random number generator of your operating system (which is much better) to mix additional randomness into the session IDs. This is done with two INI settings: session.entropy_file specifies the path to the system's random number generator. And session.entropy_length sets the number of bytes which PHP should read from this generator.

 

On a Linux server, you would use something like this:

session.entropy_file      /dev/urandom
session.entropy_length    16

 

 

 

2. Protecting the session cookie

 

The session ID can be stolen in two ways: through malicious JavaScript code in case of a cross-site scripting vulnerability, or by reading unencrypted network traffic.

 

To prevent the ID from being stolen through JavaScript, it's very important to set the HttpOnly flag of the session cookie. This tells the browser to not give JavaScript access to the cookie. You do this by activating the session.cookie_httponly setting.

 

It's also important to use HTTPS so that the network traffic between the client and the server cannot be read by attackers. You can then tell the browser to only transmit the session cookie over HTTPS and never over a plaintext HTTP connection. You do this with the session.cookie_secure setting.

 

So a proper configuration would look like this:

session.cookie_httponly    on
session.cookie_secure      on

 

 

 

3. Preventing session fixation attacks

 

If an attacker is able to set the session ID of a victim, they can simply wait until the victim has logged in and then take over the session.

 

The first step to prevent this is by only accepting session IDs from a cookie and never from a URL parameter. You do this by activating both session.use_cookies and session.use_only_cookies:

session.use_cookies         on
session.use_only_cookies    on

The second step consists of regenerating the session ID after the user has logged in. Even if an attacker has managed to find out the previous session ID, they now don't know the new one.

<?php

// this goes into your login script right after you've verified the password
session_regenerate_id(true);

 

 

 

4. Terminating the session correctly

 

A session consists of three different things: the session file on the server, the session cookie in the user's browser and the $_SESSION array in the current PHP process. All three have to be cleared in the logout procedure:

<?php

// clear $_SESSION array
$_SESSION = array();

// destroy session file on the server
session_destroy();

// ask client to delete the session cookie
$session_cookie_params = session_get_cookie_params();
setcookie(
    session_name(),
    '',
    time() - 24 * 3600,
    $session_cookie_params['path'],
    $session_cookie_params['domain'],
    $session_cookie_params['secure'],
    $session_cookie_params['httponly']
);

 

 

 

5. Setting an absolute time limit

 

In addition to all previous steps, it's important to make sure the session ends after a certain amount of time. Note that it's not enough to simply set the lifetime of the cookie, because the client can extend this forever. You need to enforce the time limit on the server.

 

When the user has just logged in, store the current time in the session file:

<?php

// this goes into the login script
$_SESSION['creation_time'] = time();  

Then check the time on every page before you accept the session:

<?php

// make the session end after 1 hour (or whatever you find appropriate)
define('SESSION_MAX_LIFETIME', 3600);

// check the lifetime of the session on every page
if (isset($_SESSION['user_id'], $_SESSION['creation_time']))
{
    $session_lifetime = time() - $_SESSION['creation_time'];
    if ($session_lifetime_seconds <= SESSION_MAX_LIFETIME) {
        // good to go
    }
    else
    {
        // the session has expired; terminate it
    }
}
Edited by Jacques1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.