ajoo Posted April 13, 2014 Share Posted April 13, 2014 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 https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/ Share on other sites More sharing options...
Skewled Posted April 13, 2014 Share Posted April 13, 2014 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 https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476012 Share on other sites More sharing options...
mac_gyver Posted April 13, 2014 Share Posted April 13, 2014 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. Link to comment https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476014 Share on other sites More sharing options...
Jacques1 Posted April 13, 2014 Share Posted April 13, 2014 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 https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476016 Share on other sites More sharing options...
Skewled Posted April 13, 2014 Share Posted April 13, 2014 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. Link to comment https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476017 Share on other sites More sharing options...
mac_gyver Posted April 13, 2014 Share Posted April 13, 2014 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 https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476024 Share on other sites More sharing options...
Skewled Posted April 13, 2014 Share Posted April 13, 2014 That should do the trick: } else { header('Location: /login.php'); die; // end execution on next line to prevent the rest of the code from executing. } Link to comment https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476027 Share on other sites More sharing options...
Jacques1 Posted April 14, 2014 Share Posted April 14, 2014 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: 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). You must prevent the session ID from being stolen through JavaScript or in transit. An attacker must not be able to set the session ID of a victim (this is called session fixation). It's important to correctly terminate the session in the logout procedure. 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 } } Link to comment https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476031 Share on other sites More sharing options...
ajoo Posted April 14, 2014 Author Share Posted April 14, 2014 hey wow !! That seems like a lot of information to ingest. Thanks loads fellas I'll read this and more on sessions and logins and be back with some more meaningful questions. Thanks all ! Link to comment https://forums.phpfreaks.com/topic/287744-secure-login-strongest-session-ids-and-secure-site-navigation/#findComment-1476089 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.