简体   繁体   中英

Is my simple user authentication system secure enough?

I've been working on this authentication system for user login and would appreciate some feedback.

My idea is this. Use sessions and one additional cookie. Session cookie and additional cookie work together. In my Login class, after i check if the username and password are correct, i call sessionStart method and send user's id from database:

public function sessionStart($id) {
    session_start();
    $cookieName = "RagingBull";
    $hash = $this->loginHash($id);
    setcookie($cookieName, $hash);
}

In my sessionStart method, a loginHash method is called. loginHash method creates hash and links together session cookie and additional cookie.

public function loginHash($id) {
    $timeStamp              = time();
    $randNumber             = mt_rand(0, 1000);
    $userId                 = $id;
    $_SESSION['timeStamp']  = $timeStamp;
    $_SESSION['randNumber'] = $randNumber;
    $_SESSION['userId']     = $id;
    $userAgent              = $_SERVER['HTTP_USER_AGENT'];
    $salt                   = "On the Waterfront";
    $ipFrag                 = substr($this->getUserIP(), 0, 5);
    $forHash                = $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
    $hash                   = md5($forHash);
    return $hash;

}

For creating a hash value, i use

  • timeStamp, which is also saved in session cookie
  • randNumber, which is saved in session cookie
  • userId, which is saved in session cookie
  • userAgent,
  • salt, which is saved internaly on the server
  • ipFrag, just a fragment of user's IP address.

I save some values in session cookie so that i can use them later when creating hash for comparison. After that, we go back to sessionStart method, and create additional cookie with returned hash value, and then user is logged in.

For authentication, i have Session class.

class Session {

public function __construct() {

    session_start();
    // checks to see if all the cookies are there
    if(!isset($_SESSION['userId']) || !isset($_COOKIE['RagingBull'])) {
        header("Location:http://localhost/login.php");
    }

    //create hash for comparison
    $hash = $this->loginHash();

    //if hashes are not the same, redirect
    if(strcmp($hash, $_COOKIE['RagingBull']) !== 0) {
        header("Location:http://localhost/login.php");
    }
}

public function loginHash() {
    $timeStamp  = $_SESSION['timeStamp'];
    $randNumber = $_SESSION['randNumber'];
    $userId         = $_SESSION['userId'];
    $userAgent  = $_SERVER['HTTP_USER_AGENT'];
    $salt       = "On the Waterfront";
    $ipFrag     = substr($this->getUserIP(), 0, 5);
    $forHash    =  $timeStamp.$salt.$userId.$ipFrag.$randNumber.$userAgent;
    $hash       = md5($forHash);
    return $hash;
}

public function getUserIP() {
    if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }

    return $ip;
}

}

To use it, i just create instance of Session class. Then, in constructor, after basic checking, there is creation of hash for comparison, i use the timeStamp, userId and randNumber from session cookie which i saved before, and combine them with user agent and ip fragment from user who requested page.

  • Is there any obvious security or logic flaws?
  • Is it secure enough?
  • Is there too much work for server to do for every page request?
  • Is any of this unnecessary?

This code does a lot of pointless things insecurely.

  • Using mt_rand() instead of random_int() .
  • Using md5($var) instead of hash('sha256', $var)
  • Using md5($password) instead of password_hash() and password_verify()
  • The "login hash" is entirely meaningless.

If you're trying to do persistent authentication (ie "remember me" cookies), just implement that .

If you're trying to protect against session attacks, just use TLS (and ensure your session ID is generated from /dev/urandom if you're still on PHP 5) and strict mode. Call session_regenerate_id(true) whenever the user logs in or logs out. Done.

The hashing here adds no value, and you're using tools that were not meant for secure authentication.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM