Question: I would like to clean up my login script and help make it safe for my database. I am a basic coder and learned what I have from tutorials, so I guess my script needs some protections, any suggestions?

```
<?php

session_start();

$email = strtolower( trim($_POST['email']));
$pass = $_POST['password'];

if ($email&&$pass){

require_once("dbconnect.php");

$query = mysql_query("SELECT * FROM users WHERE username='$email'");
$numrows = mysql_num_rows($query);
if ($numrows!=0){   
//code to login
    while ($row = mysql_fetch_assoc($query)){
        $dbusername = $row['username'];        //USERNAME IS NAME OF COLUMN IN DB
        $dbpassword = $row['password'];
        $activated = $row['activated'];

        if ($activated=='0')
            die("Your account has not been activated.(Remember to check in your email spam folder)");
    }

    //check to see if they match
    if ($email==$dbusername&&md5($pass)==$dbpassword){
        //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
        $_SESSION['username']=$email;
        header( 'Location: http://website' ) ;
    }
    else{
        echo "The password you entered is incorrect";   
    }
}
else
    die("Sorry, the email you have entered is incorrect");

}

else
    die("Please enter your email and password");

?>

```

Answer: 
Look, I rewrote it for you! This uses PDO and prepared statements, which patches the SQL injection vulnerability in the most elegant way possible (i.e. not `mysql_real_escape_string`), and also uses bcrypt for hashing passwords, which is infinitely better than one MD5 with no salt.

```
<?php
session_start();

if(isset($_POST['email']) && isset($_POST['password'])) {
    require_once 'dbconnect.php';

    $email = strtolower(trim($_POST['email']));
    $password = $_POST['password'];

    $query = $link->prepare('SELECT * FROM users WHERE username = :email LIMIT 1');
    $query->execute(array(':email' => $email));
    $row = $query->fetch();

    if($row) {
        if(!$row->activated) {
            die('Your account has not been activated. (Remember to check in your e-mail spam folder!)');
        }

        if($row->username === $email && crypt($password, $row->password) === $row->password) {
            $_SESSION['username'] = $email;
            header('Location: http://website'); # If this isn't a relative URL, try using one.
            exit();
        }
    }

    die('Invalid e-mail and/or password. Please try again.');
}
?>

```

You'll need to make a couple changes to your database, to your registration code, and to your database connection code, however.
First, I would fix the SQL injection vulnerability by changing:

```
$email = strtolower( trim($_POST['email']));
$pass = $_POST['password'];

if ($email&&$pass){

    require_once("dbconnect.php");

```

to

```
require_once("dbconnect.php");

$email = mysql_real_escape_string(strtolower( trim($_POST['email'])));
$pass = $_POST['password'];

if ($email&&$pass){

```

The next thing you could do is prevent against "session hijacking" by changing

```
if ($email==$dbusername&&md5($pass)==$dbpassword){
    //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
    $_SESSION['username']=$email;

```

to

```
if ($email==$dbusername&&md5($pass)==$dbpassword){
    //echo "You have succesfully logged-in! <a href='start.php'>Click</a> here to enter." ;
    session_regenerate_id();
    $_SESSION['username']=$email;

```

I am not sure where this login script is being used (internally or externally) but if its used externally, you could add the users ip address as a session variable and check that everytime a user returns. I would also use the crypt() function instead of md5() because md5() is NOT recommended for hashing passwords (this might depend on how many users you have and if you want to reset everyones password). I use the [PHPass class](http://www.openwall.com/phpass/)
Besides security, you could be using MySQLi (aka MySQL improved) instead of the original MySQL code because it is being deprecated. But changing to MySQLi depends on if your PHP supports MySQLi.