Login/Register security!

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Login/Register security!

Post by snarkiest »

Hi, security in my site login/register system is really low I understand it and so I need some help with it.
So this is the login.php:

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Log in!</title>
<style type="text/css">
<!--
.toutborder {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
}
.tinborder {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
    background-color: #903;
    color: #FFF;
}
.trstyle {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
}
.statusgreen {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
    background-color: #093;
    color: #FFF;
}
.statusred {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
    background-color: #903;
    color: #FFF;
}
.statusgrey {
    border: 1px solid #000;
    margin: 1px;
    padding: 1px;
    float: none;
    font-family: Tahoma;
    font-size: 10px;
    background-color: #999;
    color: #FFF;
}
-->
</style>
</head>
<body>
<?PHP
                // Connects to your Database
mysql_connect("localhost", "sc-fans", "**********") or die(mysql_error());
mysql_select_db("sc-fans") or die(mysql_error());
 
//Checks if there is a login cookie
if(isset($_COOKIE['ach_username']))
 
//if there is, it logs you in and directes you to the members page
{
$username = $_COOKIE['ach_username'];
$pass = $_COOKIE['ach_password'];
$check = mysql_query("SELECT * FROM ach_users WHERE username = '$username'")or die(mysql_error());
while($info = mysql_fetch_array( $check ))
{
if ($pass != $info['password'])
{
}
else
{
header("Location: /ach/view_ach.php");
 
}
}
}
 
//if the login form is submitted
if (isset($_POST['login'])) { // if form has been submitted
 
  // makes sure they filled it in
  if(!$_POST['username'] | !$_POST['pass']) {
  echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Message: You didn't complete all fields. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
  exit();
  }
  
  // checks it against the database
  if (!get_magic_quotes_gpc()) {
  $_POST['email'] = addslashes($_POST['email']);
  }
  $usernamec = $_POST['username'];
  $check = mysql_query("SELECT * FROM ach_users WHERE username ='$usernamec' ")or die(mysql_error());
 
//Gives error if user dosen't exist
  $check2 = mysql_num_rows($check);
  if ($check2 == 0) {
  echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Message: That user don't exist in our database. <a href='/ach/register.php'>Sign up</a> for an account today or <a href='javascript&#058;self.history.back();'>return</a>.</td></tr></table>";
  exit();
  }
    while($info = mysql_fetch_array( $check ))
    {
        $_POST['pass'] = stripslashes($_POST['pass']);
        $info['password'] = stripslashes($info['password']);
        $_POST['pass'] = md5($_POST['pass']);
        
        //gives error if the password is wrong
        if ($_POST['pass'] != $info['password'])
        {
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Message: Incorrect password, please try again. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        exit();
        }
        else
        {
        
        // if login is ok then we add a cookie
        $_POST['username'] = stripslashes($_POST['username']);
        $hour = time() + 360000;
        setcookie(ach_username, $_POST['username'], $hour);
        setcookie(ach_password, $_POST['pass'], $hour);
        
        //then redirect them to the members area
        header("Location: /ach/view_ach.php");
        }
    }
}
?>
<form action="<?PHP $_POST['PHP_SELF']; ?>" method="post">
<table width='323' class='toutborder' cellspacing='2' cellpadding='2'>
  <tr width='100%'>
    <td class='tinborder' algin='center' width='40%'>Username:</td>
    <td class='trstyle' align='center' width='60%'><input type='text' name='username'></td>
  </tr>
  <tr width='100%'>
    <td class='tinborder' algin='center' width='40%'>Password:</td>
    <td class='trstyle' align='center' width='60%'><input type="password" name="pass"/></td>
  </tr>
  <tr>
    <td colspan="2" align='center' class='trstyle'><input type='submit' name='login' value='Log in'></td>
    </tr>
</table>
</form>
</body>
</html>
And this is the register.php:

Code: Select all

 
<?PHP
include("connect.php");
include("vars.php");
 
//This code runs if the form has been submitted.
if (isset($_POST['register'])) {
        //This makes sure they did not leave any fields blank.
        if (!$_POST['username'] | !$_POST['pass'] | !$_POST['pass2'] | !$_POST['email'] | !$_POST['email2'] | !$_POST['vpncharacter'])        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Complete all of the required fields. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Checks if the username is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['username'] = addslashes($_POST['username']);
        }
        $usercheck = $_POST['username'];
        $check = mysql_query("SELECT username FROM ach_users WHERE username = '$usercheck'",$connect);
        $check2 = mysql_num_rows($check);
        //If username exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the username "; 
        echo $_POST['username'];
        echo " is already in use. Maybe you should think of new one? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //This makes sure both passwords entered match.
        if ($_POST['pass'] != $_POST['pass2']) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Your passwords did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Here we encrypt the password and add slashes if needed.
        $_POST['pass'] = md5($_POST['pass']);
        if (!get_magic_quotes_gpc()) 
        {
        $_POST['pass'] = addslashes($_POST['pass']);
        $_POST['username'] = addslashes($_POST['username']);
        }
        //This makes sure both emails enetered match.
        if ($_POST['email'] != $_POST['email2']) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Your entered e-mails did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Checks if the e-mail is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['email'] = addslashes($_POST['email']);
        }
        $emailcheck = $_POST['email'];
        $check = mysql_query("SELECT username FROM ach_users WHERE email='$emailcheck'",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the e-mail "; 
        echo $_POST['email'];
        echo " is already in use. Maybe try some other working e-mail? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Checks if the vpn character name is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['vpncharacter'] = addslashes($_POST['vpncharacter']);
        }
        $vpncharactercheck = $_POST['vpncharacter'];
        $check = mysql_query("SELECT username FROM ach_users WHERE vpncharacter='$vpncharactercheck'",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, somebody else has signed up with this "; 
        echo $_POST['vpncharacter'];
        echo " character. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
    //Now we insert it into the database.
    $insert = mysql_query("INSERT INTO ach_users (username, password, email, vpncharacter) VALUES ('".$_POST['username']."', '".$_POST['pass']."', '".$_POST['email']."', '".$_POST['vpncharacter']."')",$connect);
    $add_member = mysql_query($insert);
    echo $topregister;
    echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Good news: Your account has been successfully created. You can now <a href='/ach/login.php'>log in</a>.</td></tr></table>";
    echo $bottom;
    exit();
}
else {
echo $topregister;
echo "
      <form action='" . $_POST['PHP_SELF'] . "' method='post'>
      <table width='323' class='toutborder' cellspacing='2' cellpadding='2'>
      <tr width='100%'>
        <td colspan='2' class='tinborder' align='center' width='100%'>Hello, want to sign up? Do it below, but be sure to complete all fields and enter accurate information in case we need to contact you.</td>
      </tr>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Username:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='username'></td>
      </tr>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>E-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email'></td>
      </tr>
          <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat e-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>VPN Character:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='vpncharacter'></td>
      </tr>
      <tr>
        <td colspan='2' align='center' class='trstyle'><input type='submit' name='register' value='Create Account!'></td>
        </tr>
    </table>
    </form>";
echo $bottom;
}
?>
 
I've some questions too as I'm new to php how did I do? What about my writing style? What should I change so it is secure? Oh and later after the user is registered and logged in I want to create some text which you only see if you are logged in. Until now I do it like this:

Code: Select all

if(isset($_COOKIE['ach_username']))
{
echo "You are member!";
}
else
{
echo "You are not a member!";
}
I know it is very stupid and someone who knows the cookie name can set it and logged in as somebody else. How to make some check so it would be secure?
Also I would like to remake the login script so there would be user groups - users and admins because otherwise I do user groups like this:

For users one table in database and output:

Code: Select all

if(isset($_COOKIE['ach_username']))
{
echo "You are member!";
}
else
{
echo "You are not a member!";
}
For admins I created another table in my database which carry only 1 record (me) and so I could create a small check like this:

Code: Select all

if(isset($_COOKIE['ach_admin_password'])=='$adminpassword') {
      $adminpassword = checkpassword;
      $checkpassword = mysql_query("SELECT * FROM ach_admins WHERE password ='$adminpassword' ")or die(mysql_error());
{
echo "You are admin!";
}
else
{
echo "You are nobody!";
}
But here (^) it is very annoying to each time write the check. Can we make some global thing which can be used all around site?
Last edited by snarkiest on Mon Jun 01, 2009 1:14 pm, edited 2 times in total.
Paul Arnold
Forum Contributor
Posts: 141
Joined: Fri Jun 13, 2008 10:09 am
Location: Newcastle Upon Tyne

Re: Login/Register security!

Post by Paul Arnold »

Where to start.

- Never ever ever ever store the password in a cookie.

- Never use a variable in a database query without validating and escaping it first.

- Don't display mysql errors if queries fail. You'll tell potential hackers about your database architecture.

That's just from looking at a couple of lines.
Don't be disheartened but I'd seriously recommend starting from the beginning security-wise.
Look for a good tutorial on creating login systems that cover the security considerations and go from there.

In particular search for information on SQL Injection.
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

It's ok, I'll do my best.
But I don't want to create a new one, I'll just continue this one.

So if not to write query errors then it would look like this. I'm correct?

Code: Select all

$check = mysql_query("SELECT * FROM ach_users WHERE username = '$username'");
How to do this one?
- Never use a variable in a database query without validating and escaping it first.
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

I edited the register.php so it is clearer. Can someone check the security of it and how correct it is with all slashes and other things?
Paul Arnold
Forum Contributor
Posts: 141
Joined: Fri Jun 13, 2008 10:09 am
Location: Newcastle Upon Tyne

Re: Login/Register security!

Post by Paul Arnold »

Code: Select all

$check = mysql_query("SELECT * FROM ach_users WHERE username = '$username'");
At the moment, if someone typed their username as say '; drop table ach_users; --
There goes your table. This is an example of SQL injection.

At the very least do this:

Code: Select all

$username = mysql_real_escape_string($_POST['username']);
You don't need to start again from scratch but you need to find another way of getting the password rather than from a cookie.
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Ok, so it means that:

Code: Select all

$usercheck = $_POST['username'];
Has to be like:

Code: Select all

$usercheck = mysql_real_escape_string($_POST['username']);
And everywhere else where are $_POST value I have to put the mysql real escape string?
If so then the new register.php looks like this:

Code: Select all

<?PHP
include("connect.php");
include("vars.php");
 
//This code runs if the form ($register) has been submitted.
if (isset($_POST['register'])) {
        //This makes sure they did not leave any fields blank.
        if (!$_POST['username'] | !$_POST['pass'] | !$_POST['pass2'] | !$_POST['email'] | !$_POST['email2'] | !$_POST['vpncharacter'])        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Complete all of the required fields. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Validates the username.
        $pattern = "/^([a-zA-Z0-9])+$/";
        $username = mysql_real_escape_string($_POST['username']);
        echo $topregister;      
        if(!preg_match($pattern,$username)) {
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Username contains invalid characters. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        } 
        //Checks if the username is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['username'] = addslashes($_POST['username']);
        }
        $usercheck = mysql_real_escape_string($_POST['username']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE username = '$usercheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If username exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the username "; 
        echo $_POST['username'];
        echo " is already in use. Maybe you should think of new one? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //This makes sure both passwords entered match.
        if ($_POST['pass'] != $_POST['pass2']) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Your passwords did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Here we encrypt the password and add slashes if needed.
        $_POST['pass'] = md5($_POST['pass']);
        if (!get_magic_quotes_gpc()) 
        {
        $_POST['pass'] = addslashes($_POST['pass']);
        $_POST['username'] = addslashes($_POST['username']);
        }
        //This makes sure both emails enetered match.
        if ($_POST['email'] != $_POST['email2']) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Your entered e-mails did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Validates the e-mail.
        $pattern = "/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' .
'(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i";
        $eail = mysql_real_escape_string($_POST['email']);
        echo $topregister;      
        if(!preg_match($pattern,$email)) {
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>E-mail contains invalid characters. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        } 
        //Checks if the e-mail is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['email'] = addslashes($_POST['email']);
        }
        $emailcheck = mysql_real_escape_string($_POST['email']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE email='$emailcheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the e-mail "; 
        echo $_POST['email'];
        echo " is already in use. Maybe try some other working e-mail? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Checks if the vpn character name is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['vpncharacter'] = addslashes($_POST['vpncharacter']);
        }
        $vpncharactercheck = mysql_real_escape_string($_POST['vpncharacter']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE vpncharacter='$vpncharactercheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, somebody else has signed up with this "; 
        echo $_POST['vpncharacter'];
        echo " character. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
    //Now we insert it into the database.
    $insert = mysql_query("
                          INSERT INTO ach_users (username, password, email, vpncharacter) 
                          VALUES ('".$_POST['username']."', '".$_POST['pass']."', '".$_POST['email']."', '".$_POST['vpncharacter']."')
                          ",$connect);
    $add_member = mysql_query($insert);
    echo $topregister;
    echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Good news: Your account has been successfully created. You can now <a href='/ach/login.php'>log in</a>.</td></tr></table>";
    echo $bottom;
    exit();
}
else {
echo $topregister;
echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Hello, want to sign up? Do it below, but be sure to complete all fields and enter accurate information in case we need to contact you.</td></tr></table>";
echo "
      <form name='register' action='" . $_POST['PHP_SELF'] . "' method='post'>
      <table width='323' class='toutborder' cellspacing='2' cellpadding='2'>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Username:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='username'></td>
      </tr>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>E-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email'></td>
      </tr>
          <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat e-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>VPN Character:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='vpncharacter'></td>
      </tr>
      <tr>
        <td colspan='2' align='center' class='trstyle' /><input type='submit' name='register' value='Create Account!' /></td>
        </tr>
    </table>
    </form>";
echo $bottom;
}
?>
 
Is it correct?
Paul Arnold
Forum Contributor
Posts: 141
Joined: Fri Jun 13, 2008 10:09 am
Location: Newcastle Upon Tyne

Re: Login/Register security!

Post by Paul Arnold »

Yep. Any variables that go into your database.
Check they're in the right format too.
Eg: a number is a number, text doesn't contain any characters it shouldn't etc.
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Paul Arnold wrote: Check they're in the right format too.
Yeah, I did the username validation, but I found it difficult to write the e-mail pattern.

Code: Select all

$pattern = "/^([a-z0-9])(([-a-z0-9._])*([a-z0-9]))*\@([a-z0-9])' . '(([a-z0-9-])*([a-z0-9]))+' . '(\.([a-z0-9])([-a-z0-9_-])?([a-z0-9])+)+$/i";
Can you help me with it?
I want the patern to be a-zA-Z0-9._ @ a-zA-Z0-9 . a-zA-Z
So it accepts e-mail like: gStar_5@yaHoo77.cOm
Or: gstar@yahoo.com

But all other characters are disallowed. But ._ means they can use the "_" ?
Paul Arnold
Forum Contributor
Posts: 141
Joined: Fri Jun 13, 2008 10:09 am
Location: Newcastle Upon Tyne

Re: Login/Register security!

Post by Paul Arnold »

Code: Select all

 
if(filter_var($email, FILTER_VALIDATE_EMAIL) == FALSE) {
    //Generate an error;
}
 
Not too many people are aware of this one.
I think it's PHP5.2>
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Paul Arnold wrote:

Code: Select all

 
if(filter_var($email, FILTER_VALIDATE_EMAIL) == FALSE) {
    //Generate an error;
}
 
Not too many people are aware of this one.
I think it's PHP5.2>
What this filter will do?
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Login/Register security!

Post by kaisellgren »

The filter checks whether the provided email is valid.

Maybe you should start thinking about how you organize your code, etc. Your script looks like a peasoup... :P it makes the analysis of your script very hard.
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Ok, I just finished the register.php:

Code: Select all

<?PHP
include("connect.php");
include("vars.php");
 
//This code runs if the form ($register) has been submitted.
if (isset($_POST['register'])) {
        //This makes sure they did not leave any fields blank.
        if (!$_POST['username'] | !$_POST['pass'] | !$_POST['pass2'] | !$_POST['email'] | !$_POST['email2'] | !$_POST['vpncharacter'])        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Complete all of the required fields. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Validates the username.   
        $pattern = "/^[a-zA-Z0-9\-_]{3,}$/";
        $username = mysql_real_escape_string($_POST['username']);
        if(!preg_match($pattern,$username)) {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Your username " . $_POST['username'] . " contains invalid characters. It can contain characters a-z, A-Z and numbers 0-9. You can also use underscores (_) or dashes (-). <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        } 
        //Checks if the username is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['username'] = addslashes($_POST['username']);
        }
        $usercheck = mysql_real_escape_string($_POST['username']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE username = '$usercheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If username exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the username "; 
        echo $_POST['username'];
        echo " is already in use. Maybe you should think of new one? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Validates the password.
        $pattern = "/^[a-zA-Z0-9]{6,16}$/";
        $pass = mysql_real_escape_string($_POST['pass']);
        if(!preg_match($pattern,$pass)) {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Your password " . $_POST['pass'] . " contains invalid characters or is too long or too short. It can contain characters a-z, A-Z and numbers 0-9. And password has to be at least 6 characters short on at most 16 characters long. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        } 
        //This makes sure both passwords entered match.
        if ($_POST['pass'] != $_POST['pass2']) {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Your passwords did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Here we encrypt the password and add slashes if needed.
        $_POST['pass'] = md5($_POST['pass']);
        if (!get_magic_quotes_gpc()) 
        {
        $_POST['pass'] = addslashes($_POST['pass']);
        $_POST['username'] = addslashes($_POST['username']);
        }
        //This makes sure both emails enetered match.
        if ($_POST['email'] != $_POST['email2']) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Your entered e-mails did not match. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Validates the e-mail.
        $email = mysql_real_escape_string($_POST['email']);
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>E-mail contains invalid characters. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        } 
        //Checks if the e-mail is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['email'] = addslashes($_POST['email']);
        }
        $emailcheck = mysql_real_escape_string($_POST['email']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE email='$emailcheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, the e-mail "; 
        echo $_POST['email'];
        echo " is already in use. Maybe try some other working e-mail? <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        //Checks if the vpn character name is in use.
        if (!get_magic_quotes_gpc()) {
        $_POST['vpncharacter'] = addslashes($_POST['vpncharacter']);
        }
        $vpncharactercheck = mysql_real_escape_string($_POST['vpncharacter']);
        $check = mysql_query("
                             SELECT username FROM ach_users WHERE vpncharacter='$vpncharactercheck'
                             ",$connect);
        $check2 = mysql_num_rows($check);
        //If email exists then give error.
        if ($check2 != 0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Sorry, somebody else has signed up with this "; 
        echo $_POST['vpncharacter'];
        echo " character. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
        echo $bottom;
        exit();
        }
        $ip = mysql_real_escape_string($_SERVER['REMOTE_ADDR']);
    //Now we insert it into the database.
    $insert = mysql_query("
                          INSERT INTO ach_users (username, password, regdatetime, ip, email, vpncharacter) 
                          VALUES ('".$_POST['username']."', '".$_POST['pass']."', NOW(), '$ip', '".$_POST['email']."', '".$_POST['vpncharacter']."')
                          ",$connect);
    $add_member = mysql_query($insert);
    echo $topregister;
    echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Good news: Your account has been successfully created. You can now <a href='/ach/login.php'>log in</a>.</td></tr></table>";
    echo $bottom;
    exit();
}
else {
echo $topregister;
echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Hello, want to sign up? Do it below, but be sure to complete all fields and enter accurate information in case we need to contact you.</td></tr></table>";
echo "
      <form name='register' action='" . $_POST['PHP_SELF'] . "' method='post'>
      <table width='323' class='toutborder' cellspacing='2' cellpadding='2'>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Username:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='username'></td>
      </tr>
      <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat password:</td>
        <td class='trstyle' align='center' width='60%'><input type='password' name='pass2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>E-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email'></td>
      </tr>
          <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>Repeat e-mail:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='email2'></td>
      </tr>
        <tr width='100%'>
        <td class='tinborder' align='center' width='40%'>VPN Character:</td>
        <td class='trstyle' align='center' width='60%'><input type='text' name='vpncharacter'></td>
      </tr>
      <tr>
        <td colspan='2' align='center' class='trstyle' /><input type='submit' name='register' value='Create Account!' /></td>
        </tr>
    </table>
    </form>";
echo $bottom;
}
?>
 
So is the register.php secure enough? Are there any missed things?
Oh, and how about mysql_escape_string and mysql_real_escape_string. What is the difference?
Also when to use get_magic_quotes_gpc? I know that there are guides out there, but no guide is better than explanation here. (:
Because until know i didn't know where to use mysql_real_escape_string until Paul Arnold said: Yep. Any variables that go into your database. Now it is clear to me. ;)
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Ok, and now I'm working on the new login.php:

So here it bellow my new log in. Of course not ready yet. I stuck on the place where session needs to start.

Code: Select all

 
<?PHP
include("connect.php");
include("vars.php");
 
if(isset($_POST['login']))
{
//If password field and username field is not completed give error and exit script. It could like below. I think it is correct.
 
    if (!$_POST['username'] | !$_POST['pass']) {
    echo $topregister;
    echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>We warned you. Did we not? Complete all of the required fields. <a href='javascript&#058;self.history.back();'>Return</a>.</td></tr></table>";
    echo $bottom;
    exit();
    }
 
//Now if they are filled in check it against db. 
        // Assign the username and password from the form to variables.
        $username = mysql_real_escape_string($_POST['username']);
        $password = mysql_real_escape_string($_POST['pass']);
        $encrypted_password=md5($password);
        
        $sql= mysql_query("SELECT * FROM `ach_users` WHERE `username`='$username' AND `password`='$encrypted_password'",$connect);
        $result=$sql;
        
        // This counts to see how many rows were found, there should be no more than 1
        $count=mysql_num_rows($result);
        if($count!=1){
            echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: The password or username which you enetered is wrong.  <a href='javascript&#058;self.history.back();'>Return</a>.";
        exit();
        }
        
        $username = mysql_real_escape_string($_POST['username']);
        $password = mysql_real_escape_string($_POST['pass']);
        $encrypted_password=md5($password);
        
        $active=1;
        $check = mysql_query("SELECT * FROM `ach_users` WHERE `username`='$username' AND `password`='$encrypted_password' AND `Active`='$active'",$connect);
        $result1 = $check; 
        
        $check2 = mysql_num_rows($result1);
        if($check2!=0) 
        {
        echo $topregister;
        echo "<table width='323' class='toutborder' cellspacing='2' cellpadding='2'><tr width='100%'><td class='tinborder' align='center' width='10%'>Error: Your account is suspened, you can't log in anymore.  <a href='javascript&#058;self.history.back();'>Return</a>.";
        echo $bottom;
        exit();
        }
        // If result matched $username and $password, table row must be 1
 
        // Register $username, $password and send the user to the file "login_success.php"
 
        session_start(); 
        $_SESSION['ach_login'] = ''; 
        header("location:/ach/view_ach.php");
}
else
{
    echo $toplogin;
    echo "<form action='" . $_POST['PHP_SELF'] . "' method='post'>
<table width='323' class='toutborder' cellspacing='2' cellpadding='2'>
  <tr width='100%'>
    <td class='tinborder' algin='center' width='40%'>Username:</td>
    <td class='trstyle' align='center' width='60%'><input type='text' name='username'></td>
  </tr>
  <tr width='100%'>
    <td class='tinborder' algin='center' width='40%'>Password:</td>
    <td class='trstyle' align='center' width='60%'><input type='password' name='pass'/></td>
  </tr>
  <tr width='100%'>
    <td class='tinborder' algin='center' width='40%'>Remember:</td>
    <td class='trstyle' align='center' width='60%'><input type='checkbox' name='remember'/></td>
  </tr>
  <tr>
    <td colspan='2' align='center' class='trstyle'><input type='submit' name='login' value='Log In!'></td>
    </tr>
</table>
</form>";
echo $bottom;
}
?>
So what I wanted to ask is what to do with the session and how?

Code: Select all

session_start(); 
        $_SESSION['ach_login'] = '1'; //what variable to place there?
                $_SESSION['ach_username'] = '$_POST['username']';
        header("location:/ach/view_ach.php");
I will need sessions later in my page for some buttons or menus which are only visible to logged in members. What variables should I store? And how after that to get them? I would do like this:

if(isset($_SESSION['ach_login'])==1) {
echo "Welcme " . $_SESSION['ach_username'] . " to our site."; //will it display log in name there?
echo "Edit users";
}
snarkiest
Forum Commoner
Posts: 30
Joined: Mon May 04, 2009 10:06 am
Location: Latvia
Contact:

Re: Login/Register security!

Post by snarkiest »

Can anyone help?
User avatar
kaisellgren
DevNet Resident
Posts: 1675
Joined: Sat Jan 07, 2006 5:52 am
Location: Lahti, Finland.

Re: Login/Register security!

Post by kaisellgren »

Yeah you can store the number 1 there, but it would be more clever to do something like:

Code: Select all

$_SESSION['logged_in'] = 'regular';
$_SESSION['logged_in'] = 'admin';
etc.
Or with more advanced systems, the value can be a reference to a table row.

I recommend you to read some basic security books and articles, there are thousands of those just give Google a try. It would make everything much easier for you.

Also, learning some general design practises and structuring your code would not hurt.
Post Reply