Jump to content

Using PHP to create secure login


limitphp

Recommended Posts

I need some help with how to go about creating secure login with a username and password.

 

I have a table "Users" that has a userID, username and password fields.

 

The way I went about it last time was they enter their username and password.  I check those against the database.  Once it matches, I grabbed the userID and stored a hash of that in a cookie.

Then, whenever they did anything else, I just made sure the userID hash in the cookie matched the userID hash in the user table.

 

I'm fairly new to trying to make websites a tiny bit secure.  Is that logic sound?

The major problem I see with it, is that the userIDs in the table are auto_incremented, so they'd just be 1,2,3, etc.  They'd obviously be too easy for someone to guess.

Should I save a hash of the username and password instead in the cookie?

 

If so, do I even need a userID in the users table?

 

Do most websites (Digg, hotmail, gmail, amazon, etc) have a standard way of doing logins?

 

Any help would be greatly appreciated.

 

I'm using wampserver , phpAdmin version 5.2.6

 

Link to comment
Share on other sites

I have attached 2 code snippets below. One is a smarty template (easily converted back to HTML) and the other is a class snippet showing how to do a login function with a session.

 

Smarty Template

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title>Marble Fantasy - The Beauty of Natural Stone</title>

<script type="text/javascript" src="tooltip.js">
</script>

<link rel="stylesheet" href="style.css" type="text/css" charset="utf-8" />

</head>

<body>

  <div id="wrapper">
    <div id="header">
<div id="menu" align="center">
<a href="index.php">Update Welcome</a>|
<a href="displaynews.php">Display News</a>|
<a href="displaywork.php">Display Work</a>|
<a href="displayquotes.php">Display Quotes</a>|
<a href="displayadmins.php">Display Admins</a>
	</div>
</div>
    <div id="left">
    <div id="logo">
        <h1><a href="index.php">Marble Fantasy</a></h1>
        <p>Administration Panel</p>
      </div>
  <div id="random">
        <h2>Random Work Samples</h2>
{$randomwork}
      </div>
    </div>

    <div id="right">
{$error}<BR>
<form action="login_cls.php" method="post">
<input type="hidden" name="do" value="login">
Username:<BR><input type="text" name="username" value={$username}><br/>
Password:<BR><input type="password" name="password"/><br/>
<input type="submit" name="submit" value="Login"/>
</form>
    </div>
    <div class="clear"> </div>
    <div id="spacer"> </div>
    <div id="footer">
      <div id="copyright">
        <a href="#">Terms & Conditions</a>|<a href="#">Privacy Policy</a>|<a href="#">Copyright Notice</a>
      </div>
  <div id="footerline"></div>
    </div>

  </div>
</body>
</html>

 

Login Class

function set_user_login($username, $password)
{
$username=mysql_real_escape_string($username);
$password=mysql_real_escape_string($password);

     $query = "select salt from user where username='$username' limit 1";
     $result = mysql_query($query);

     if (mysql_num_rows($result) > 0)
     { 

          $user = mysql_fetch_array($result);

          $encrypted_pass = md5(md5($password).$user['salt']);

          $query = "select ID, username from user where username='$username' and password='$encrypted_pass'";
          $result = mysql_query($query);

          if (mysql_num_rows($result) > 0)
          {
               $user = mysql_fetch_array($result);
               $userid = $user['ID'];
               $encrypted_id = md5($user['userid']);
               $encrypted_name = md5($user['username']);

               $_SESSION['userid'] = $userid;
               $_SESSION['username'] = $username;
               $_SESSION['encrypted_id'] = $encrypted_id;
               $_SESSION['encrypted_name'] = $encrypted_name;

               $this->response = 'Correct';
          }
          else
          { 
               $this->response = 'Invalid Password';
          }
     }
     else
     {
          $this->response = 'Invalid Username';
     } 
}

function get_user_login()
{
return $this->response;
}

function set_user_logout()
{
     session_unset ();
     session_destroy ();
 echo"You have been successfully logged out, you will be redirected shortly.";
 echo"<META HTTP-EQUIV=\"Refresh\" Content=\"2;URL=index.php\">\n";
}

}

 

Then on each page you need to protect with the login script include the following...

 

$auth= new auth;

if (!$auth->set_is_authed()) 
{
     die (require("login.php"));
}

if ($auth->set_is_authed()) 
{
     $logout="<a href=\"logout.php\">LOGOUT</a>";
}

class auth{

var $auth;

function set_is_authed()
{
     if (isset($_SESSION['username']) && (md5($_SESSION['username']) == $_SESSION['encrypted_name']))
     {
          return true;
     }
     else
     {
          return false;
     }
}

}

Link to comment
Share on other sites

Thanks guys!

 

I've never used sessions before, and I've only briefly heard about them.

 

So, I guess its going to be somewhat similar to what I've done before, only instead of storing the variables in a cookie and checking the cookie, I'll store them in a session?

 

Give me a little time here, I need to wrap my head around the this.  I'm going to go over that code about 10 more times.  It'll take me a little while to grasp this.

 

Thanks again.

Link to comment
Share on other sites

The cookie that the session creates only contains the session ID, not any of the session data.  The session data is stored on the SERVER, not the clients machine.  You shouldn't store any sensitive data in a cookie as anybody can read/manipulate them.

Link to comment
Share on other sites

The session id itself is sensitive data. The only way to be totally secure is to use SSL. Even with session regeneration, it only takes an idle user and some sniffing to take over a session with plain text cookies.

 

The question is, is the data important enough to warrant an SSL cert... or is it important enough to the cracker to put the effort in to try to sniff out authorized sessions. In most cases, this is a no and sessions in plain text should be secure enough... Just keep backups and use a different password for your cpanel/ftp/shell and web interface login.

Link to comment
Share on other sites

The session id itself is sensitive data. The only way to be totally secure is to use SSL. Even with session regeneration, it only takes an idle user and some sniffing to take over a session with plain text cookies.

 

The question is, is the data important enough to warrant an SSL cert... or is it important enough to the cracker to put the effort in to try to sniff out authorized sessions. In most cases, this is a no and sessions in plain text should be secure enough... Just keep backups and use a different password for your cpanel/ftp/shell and web interface login.

How does one manipulate session data with only the ID?  I understand how they can get at the session data if on shared hosting via another host that uses the same session path, but how from the client with only the session id?

Link to comment
Share on other sites

What about forums and other sites like digg, amazon, igoogle, etc that allow a user to remember them even after they leave the website and turn the computer off.  The next day they goto the website and their info is still remembered.  in other words, they don't have to log back on.

 

Can you only do that with a cookie?

 

If so, what should you store in that cookie?

Link to comment
Share on other sites

CroNiX

 

With the session id, an attacker can hijack the session... the attacker now has the credentials of whatever user they stole it from... This may not give them the session data directly, but they'd have whatever it was your passwords were keeping them from ;)

 

limitphp

 

Your best bet here is a custom session handler, that allows for variable expiry dates.

Link to comment
Share on other sites

CroNiX

 

With the session id, an attacker can hijack the session... the attacker now has the credentials of whatever user they stole it from... This may not give them the session data directly, but they'd have whatever it was your passwords were keeping them from ;)

 

limitphp

 

Your best bet here is a custom session handler, that allows for variable expiry dates.

 

Is it easy to set a session to expire in two weeks?

 

Link to comment
Share on other sites

If you want all your sessions to expire in two weeks, no.

 

If you want the user to be able to choose, it gets a bit trickier.

 

Yeah, I would want the user to be able to choose, and check a "remember me" box.

Well, if the session puts a cookie on the user's machine and using cookies puts a cookie on a user's machine, then wouldn't one of the only major differences be in what is stored on that cookie?

 

I guess the session would be something that links to a user's info in the database only temporarily.

the cookie, you'd probably store info that links to the user's info permanently?

Link to comment
Share on other sites

So, even though, sessions and cookies could both be compromised, in that someone could get the sessionID or whatever info you store on a regular cookie, with the session cookie, its only a temporary ID, so not as much harm done.

 

Is it possible for a session cookie to last a while sometimes, but not all the time?

 

And by doing that, you start to close the gap a little in one being more secure than the other.

But websites do it all the time, like igoogle for instance.

Link to comment
Share on other sites

You gotta find a balance. Plain text cookies CAN be sniffed (it's not easy, though)... if your data is important enough, buy an SSL certificate for $100-400/year.

 

With sessions, you can use what's known as session regeneration. A new ID is generated every page request, so unless the user is idle their ID will change several times a minute. This makes sniffing/spoofing very difficult, and social engineering near impossible (by the time the attacker fools the user into giving up their ID, it's changed). This is done with a single function call ( session_regenerate_id() )

 

And yes, if you create a custom session handler, you can have variable session expiry dates.

Link to comment
Share on other sites

You gotta find a balance. Plain text cookies CAN be sniffed (it's not easy, though)... if your data is important enough, buy an SSL certificate for $100-400/year.

 

With sessions, you can use what's known as session regeneration. A new ID is generated every page request, so unless the user is idle their ID will change several times a minute. This makes sniffing/spoofing very difficult, and social engineering near impossible (by the time the attacker fools the user into giving up their ID, it's changed). This is done with a single function call ( session_regenerate_id() )

 

And yes, if you create a custom session handler, you can have variable session expiry dates.

 

So, if they login without checking "remember me" use the session regeneration.

And if they select "remember me" use the custom session handler with variable expiry date.

How do you create a custom session handler with a variable expiration date?

Link to comment
Share on other sites

No, you're going to use session regeneration for both. The only difference is one will expire when the browser closes, the other will expire in x hours/days/months ect.

 

Creating a custom session handler will be your first step. Here's a good start

http://www.phpbuilder.com/columns/ying20000602.php3

 

Once you have your handler built, post here or PM me and I'll help you to get the variable time down. This won't be easy... properly implementing security measures rarely is.

Link to comment
Share on other sites

No, you're going to use session regeneration for both. The only difference is one will expire when the browser closes, the other will expire in x hours/days/months ect.

 

Creating a custom session handler will be your first step. Here's a good start

http://www.phpbuilder.com/columns/ying20000602.php3

 

Once you have your handler built, post here or PM me and I'll help you to get the variable time down. This won't be easy... properly implementing security measures rarely is.

 

Will do.  Thanks for all your help.

Link to comment
Share on other sites

I've been reading the page you sent, and I must say, its going to take me a while to understand it all.

 

What if, you created a temporary table, and in that table you stored a unique ID, userID, and an expiration date.

 

And then you stored the unique ID on a cookie, and set the expiration date whenever you wanted.

You then take that uniqueID and put it in this table along with the userID and expiration date.

 

Then you can have a cookie that lasts as long as you want, and you don't have to store any permanent data on it.

 

And every day or so, you flush the table of all entires with expired dates.

 

Could that work?

Link to comment
Share on other sites

You're describing EXACTLY what sessions do :D

 

If you create that functionality, and follow the format, you can use PHP's session engine to populate everything for you!

 

First, check out how sessions work. Check this out

http://www.tizag.com/phpT/phpsessions.php

 

Once you get comfortable with using them, you can start on your own handler, that uses a database to store the information :D

 

I'm working on a sample class for you that implements variable session expiry time. It'll seem overwhelming at first, jsut go through it line by line and explain what you don't understand.

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.