Web Hosting Talk







View Full Version : [PHP/MySQL] Cookies/Sessions | User Login


JustinSmall
10-25-2008, 06:56 AM
Hello, I've done it in the past, but on small little dinky sites; on the login check, if the cookies weren't set I set the cookie for the username and userid, and then set sessions aswell.
The basis of it was so that on returning to the site, it would check the session to see if it was initiated, if it wasn't it would then see if you had cookies set for a username and id. If you did then it would create the session for the user based off of the username/id cookie.
Now is this really safe? Or is there a way to make it safer?

JustinSmall
10-25-2008, 09:09 AM
Plus unwillingy gainging this error:
Parse error: syntax error, unexpected '[' in C:\xampplite\htdocs\includes\functions\user_actions.php on line 24
I've dug n dug, but I've been looking at coding for about 6 hours now (not on this particular code lol), so my mind is getting dizzy with code lol
line 24 is
$_SESSION['username'] = info['username']; // Set Session Username
<?
function checkLogin() {
if (!isset($_SESSION['logged']) or $_SESSION['logged'] == 0) { // User Is NOT Logged In
if (isset($_COOKIE['username']) && isset($_COOKIE['id'])) { // Checks If Cookies ARE Set!
$_SESSION['username'] = $_COOKIE['username'];
$_SESSION['id'] = $_COOKIE['id'];
$_SESSION['logged'] = 1;
}
} else {
$_SESSION['logged'] == 0;
print("You are not logged in");
}
function doLogin() {
if ($_SESSION['logged'] == 1) { // User Is Not Logged In
$username = stripslashes($_POST['username']); // Strip Slash Username
$password = md5($_POST['password']); // MD5 Encrypt Password
$sql = "SELECT * FROM gurubase WHERE username = " .$username. "AND password = " .$password;
$info = mysql_fetch_array($sql);
$numsql = mysql_num_rows($sql);
if ($numsql == 1){ // If User Does Exist
$_SESSION['id'] = $info['id']; // Set Session ID
$_SESSION['username'] = info['username']; // Set Session Username
$_SESSION['logged'] = 1; // Set Session Active
if ($_POST['cookieme'] == 1){ // If User Opts Cookies
setcookie('username', $info['id'],2592000 + time()); // Set Cookie Username
setcookie('id', $info['id'], 2592000 + time()); // Set Cookie Password
}
} else if ($numsql == 0){ // If User Does NOT Exist
exit("Invalid Username or Password");// Set Exit With Error
}
} else {
exit("You are already Logged In!"); // User Is Logged In, Exit With Error
}
}
?>

JustinSmall
10-25-2008, 10:16 AM
Was missing a $ , wonderful :D

ThatScriptGuy
10-25-2008, 12:55 PM
Your method of setting up sessions is VERY unsafe. It basically means that anyone can go and modify their cookie and put someone else's username/userid in their cookie, and they are instantly authenticated as that user....Why even have passwords if that's the case?
So, to answer your question - That is not a good way to do it, at all. If the user doesn't have a session, then make them log in again...

JustinSmall
10-25-2008, 03:06 PM
I read articles daily, and tutorials daily n stuff, to see how other people code.
I have noticed this in quite a few membership tutorials, not done exactly coded like this, but coded with the same idea.
Doesn't the person have to know the users id though? Should I put a secret combination in there aswell?
Like make a random number generated in there...
then set a cookie for the random number, that way the user has to know the id, username, and random number?
:) I think it would work, and only be an extra line of coding here and there.

Codebird
10-26-2008, 04:32 PM
yeah with a randomly created code then md5ed it should be secure never looked at any tutorial of that kind but I am sure it will be a solution for the security issue that Kevin mentioned

JustinSmall
10-26-2008, 09:07 PM
No, I mean like a wildcard.
s8d93l278os
Just a random string.
<?php
function genWild() {
$length = 10;
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters))];
}
return $string;
}
echo genWild();
?>
This is a demonstration...
it would produce something like I stated above.
Then in my the mysql database I could have 'wildcard' or something, and during the login phase, you would need the username and password, then it would create the cookie (if you opted during login to use cookies) for the id, username, and wildcard… that way if someone was trying guess someones info, they would need the wildcard aswell.
I will tighten up the security on that code a little bit, so that way it will check the database for the three entries… because with the way that code is set at the moment it doesn't check against anything.

Paul
10-26-2008, 09:11 PM
You do know sessions_start() sets a cookie? (session.use_only_cookies should be set)
Let the internal session handler.. handle things for you instead of getting around its security.

JustinSmall
10-26-2008, 09:11 PM
What do you mean by that?

Paul
10-26-2008, 09:15 PM
When you set a session in PHP. It sets a cookie containning the session_id.
Let's try this a different route.
Answer this:
Why are you using a cookie?

JustinSmall
10-26-2008, 09:17 PM
Basically, I want the user to be able to opt to be logged in at all times, I don't want them to have to login each time they close then reopen the browser. I am on WHT a lot reading, not always posting, and when I go to post and have to login, it's very annoying. I really do prefer to just keep logged in.
This is my new solution (will probably be added onto again!)
function checkCookieOpt() {
if (!isset($_SESSION['logged']) or $_SESSION['logged'] == 0) { // User Is NOT Logged In
if (isset(isset($_COOKIE['id']) && isset($_COOKIE['wildcard'])) { // Checks If Cookies ARE Set!
$cookie_id = $_COOKIE['id'];
$cookie_wildcard = $_COOKIE['wildcard'];
$check = mysql_query("SELECT * FROM %table here% WHERE id = '$cookie_id' AND wildcard = '$cookie_wildcard'");
$checknum = mysql_num_rows($check);
if($checknum == 1){
$_SESSION['id'] = $_COOKIE['id'];
$_SESSION['logged'] = 1;
}
}
} else {
$_SESSION['logged'] = 0;
}
}

Paul
10-26-2008, 09:20 PM
session_set_cookie_params
Set the lifetime to 0 and it'll stay alive as long as your cookie.
You are allowing people to use a cookie versus using a cookie <- That's what does not make sense to me.

JustinSmall
10-26-2008, 09:26 PM
again, what do you mean by that?

JustinSmall
10-26-2008, 09:28 PM
I WANT to have the user select 'cookie me' so that they will be logged in until they delete the cookies, OR don't opt to and let the session die.
I don't want them to automatically be logged in forever, I just want them to have the option.
I think I went a good way in doing this.

Paul
10-26-2008, 09:30 PM
Here is my argument:
You are using php session system. By default php session system sets a cookie.
The secondary option you have is to set a cookie containing a user and id.
I think you could get better results by properly configuring the php session options compared to making a possible security nightmare.

JustinSmall
10-26-2008, 09:33 PM
What is wrong with what I am doing, how would someone come up with the id and 10 digit wildcard???
I want the cookie to be set for the userid, so that way I can put a session for the ID, and run the majority of my functions by the session user id.

Paul
10-26-2008, 09:37 PM
I'm trying to tell you. You are doing the same twice with both options. You are trying to correct a misconfiguration of sessions with a possible security issue.
You are offering your users
"Set a cookie via sessions"
"Set a cookie via my own hack"
I personally think you would be better suited to configure your session system better.

Codebird
10-27-2008, 04:45 PM
I advice you to go with what Paul is saying (never knew of what he's saying until I read it)... So if php offers u a proper cookie for the session why would you want to make a turn around and do it yourself
1- u're losing time coding
2- I am 100% sure u'll not be as secure as u will be when u use what they're offering

etogre
10-27-2008, 07:46 PM
Let's say we want to store the user ID in a cookie so we can retrieve it and use it.
md5 hash the un-encrypted cookie data, so if the user id is 1, we'll end up with c4ca4238a0b923820dcc509a6f75849b.
Next we'll run the unencrypted data through mcrypt. Then we'll append our MD5 stamp to it and set the cookie. When validating the cookie we'll make sure the hash of the decrypted data matches our unencrypted hash (the one before encryption).
So here's a vague idea of the code (untested)
<?php
function encrypt($data, $key ='289skd92kladks92kod0ogsdGkasf') // make the key as random as possible
{
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv);
$hash = md5($data);
return $enc.$data ;
}
function decrypt($data, $key ='289skd92kladks92kod0ogsdGkasf') // make sure keys match
{
$hash = substr($data, -32);
$enc = substr($data, 0, -32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $enc, MCRYPT_MODE_ECB, $iv);
return (md5($dec) === $hash) ? $dec : false;
}
set_cookie('test', encrypt(1), time()+60*60*24*7);
if ($userid = decrypt($_COOKIE['test'])
echo $userid;
else
echo 'forged cookie';
?>
For added security we can add a unique session id (use uniqid() (http://us.php.net/manual/en/function.uniqid.php)), store it in a "sessions" table in our database and in our cookie data. Then we can check our sessions table for each request and see if the actual data exists, periodically deleting data from the table on a "last activity" type thing. We could also check the browser and/or IP if we were feeling super sketchy, but I wouldn't reccomend that.

Paul
10-27-2008, 08:02 PM
Let's say we want to store the user ID in a cookie so we can retrieve it and use it.
md5 hash the un-encrypted cookie data, so if the user id is 1, we'll end up with c4ca4238a0b923820dcc509a6f75849b.
Next we'll run the unencrypted data through mcrypt. Then we'll append our MD5 stamp to it and set the cookie. When validating the cookie we'll make sure the hash of the decrypted data matches our unencrypted hash (the one before encryption).
So here's a vague idea of the code (untested)
<?php
function encrypt($data, $key ='289skd92kladks92kod0ogsdGkasf') // make the key as random as possible
{
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$enc = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB, $iv);
$hash = md5($data);
return $enc.$data ;
}
function decrypt($data, $key ='289skd92kladks92kod0ogsdGkasf') // make sure keys match
{
$hash = substr($data, -32);
$enc = substr($data, 0, -32);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$dec = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $enc, MCRYPT_MODE_ECB, $iv);
return (md5($dec) === $hash) ? $dec : false;
}
set_cookie('test', encrypt(1), time()+60*60*24*7);
if ($userid = decrypt($_COOKIE['test'])
echo $userid;
else
echo 'forged cookie';
?>
For added security we can add a unique session id (use uniqid() (http://us.php.net/manual/en/function.uniqid.php)), store it in a "sessions" table in our database and in our cookie data. Then we can check our sessions table for each request and see if the actual data exists, periodically deleting data from the table on a "last activity" type thing. We could also check the browser and/or IP if we were feeling super sketchy, but I wouldn't reccomend that.
While that method is infact more secure it does not explain why he needs the cookie in the first place. You are building your own session system, Not a bad one I might but thats what he was looking for.

etogre
10-27-2008, 08:13 PM
I meant to say that's for writing cookies to keep the user logged in (when they select the "Stay Logged in?" box). If they don't select the box I agree with just going with native php sessions.
On that note the only thing I store in cookies for things I develop is User ID's and flash data. Storing the username like the OP was doing is kind of redundant since you'll pull all that data out anyways on each request.

Paul
10-27-2008, 11:20 PM
I meant to say that's for writing cookies to keep the user logged in (when they select the "Stay Logged in?" box). If they don't select the box I agree with just going with native php sessions.
On that note the only thing I store in cookies for things I develop is User ID's and flash data. Storing the username like the OP was doing is kind of redundant since you'll pull all that data out anyways on each request.
and my "point" was the "Stay logged in" feature can be done just by setting the session cookie to expire later along with the session expiration.

biggerboy
10-29-2008, 06:12 PM
I know its not secure by all I ever did was just create a cookie ID that I stored in the DB. So I would change it every time they logged in, and delete the value when they logged out. You could just MD5 hash check them and its really easy to code in.
I have been planning to just using session_set_cookie from now on, but haven't needed to code anything that will need to use it since I really looked into it.