sanjsimi Posted May 20, 2017 Share Posted May 20, 2017 (edited) Hi, i creating a login form with cookies and i want to know if my code is secure, do i need extra protection for cookies ? I want to know because i will store that hash in database and check if it same when user come back and make new hash then store new in database. This is my script: Login.php <?php include "../config.php"; if (isset($_COOKIE['hash']) && isset($_POST['uid']) && isset($_COOKIE['uname'])) { die("You are already logged in."); } if (isset($_POST['submit'])) { $username = htmlentities(strip_tags($_POST['username'])); $password = htmlentities(strip_tags($_POST['password'])); if ($username == '' || $password == '') { $error = 'Please enter username and password.'; } else { $data = $users->user_login($username, $password); if ($username == $data['username'] && password_verify($password, $data['password'])) { //$error = 'login user'; $hash = sha1(mt_rand(6000, 9000)); setcookie('hash', $hash, time()+60*60*24*365); setcookie('uid', $data['user_id'], time()+60*60*24*365); setcookie('uname', $data['username'], time()+60*60*24*365); header("Location: login-success.php"); exit(); } else { $error = 'Invalid username or password.'; } } } ?> <form action="" method="post" class="login-form"> <label for="username">Username</label> <input type="text" name="username" id="username"> <label for="password">Password</label> <input type="password" name="password" id="password"> <input type="submit" name="submit" value="Login"> </form> Logout.php <?php if (isset($_COOKIE['hash']) && isset($_COOKIE['uid']) && isset($_COOKIE['uname'])) { unset($_COOKIE['hash']); unset($_COOKIE['uid']); unset($_COOKIE['uid']); setcookie('hash', null, -1); setcookie('uid', null, -1); setcookie('uname', null, -1); header("Location: index.php"); exit(); } ?> User class class Users { protected $db; function __construct(PDO $db) { $this->db = $db; } /* * login user * * */ public function user_login($username, $password) { $query = $this->db->prepare("SELECT user_id, username, password FROM users WHERE username = :username"); $query->execute(array(':username' => $username)); if ($query->rowCount() > 0) { return $query->fetch(); } } Edited May 20, 2017 by sanjsimi Quote Link to comment Share on other sites More sharing options...
requinix Posted May 20, 2017 Share Posted May 20, 2017 I'll ask you one question: If I were to tell you that I could magically change the cookies on my computer to use any values I wanted, how would that affect your application? Because I can totally change the cookies on my computer to use any values I wanted. Anyone can do that. 1 Quote Link to comment Share on other sites More sharing options...
sanjsimi Posted May 20, 2017 Author Share Posted May 20, 2017 It will not be nice news for me I know that cookies can be changed but i see all other website using cookies for login systems. Quote Link to comment Share on other sites More sharing options...
DulongC Posted May 20, 2017 Share Posted May 20, 2017 I see a lot of people texting and driving... doesn't make it safe.Cookies are a very insecure way of managing user access. At most, I would store the user's username in a cookie so all they need to do is enter their password. If you're adamant about keeping someone logged in using cookies, I would read this: https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence 1 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted May 20, 2017 Share Posted May 20, 2017 They use cookies for a very specific purpose. Either they store the session ID which points to a server-side session (a PHP standard feature), or they store the actual user data but protect its authenticity with a message authentication code (which is more exotic and complex). In any case, I strongly recommend you don't invent your own mechanism. This usually doesn't end well. Use the standard sessions in PHP. 2 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted May 20, 2017 Share Posted May 20, 2017 Cookies are a very insecure way of managing user access. Um, what? This is how the WWW works. Cookies are in fact much more secure than many of the alternatives (like HTTP Basic authentication or tokens in the URL). 1 Quote Link to comment Share on other sites More sharing options...
requinix Posted May 20, 2017 Share Posted May 20, 2017 Um, what? This is how the WWW works. Cookies are in fact much more secure than many of the alternatives (like HTTP Basic authentication or tokens in the URL).I'm sure DulongC meant that storing the data in cookies is insecure, not the literal act of using cookies at all. We all know cookies are important and a fundamental aspect of how the internet works... well, except for the EU. 1 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted May 20, 2017 Share Posted May 20, 2017 The OP wants to implement sessions and correctly pointed out that websites commonly use cookies for this. Replying with “cookies are insecure” and suggesting that websites which use them somehow got it all wrong doesn't make a lot of sense. The answer I would have expected is: Use standard PHP sessions. Quote Link to comment Share on other sites More sharing options...
sanjsimi Posted May 21, 2017 Author Share Posted May 21, 2017 So using a session i will be more secure, using https protocol ? session_regenerate_id(true); $_SESSION['ss'] = $data['user_id']; header("Location: login-success.php"); exit(); Quote Link to comment Share on other sites More sharing options...
DulongC Posted May 21, 2017 Share Posted May 21, 2017 (edited) Yes, cookies are important and they can be very useful when used properly. However my understanding of: I want to know because i will store that hash in database and check if it same when user come back Means that he wants to go beyond a standard session and keep his user's logged in every time they visit the site using a cookie. When this is done, it creates a potential security hole as I can now take steal your cookie, put it on my computer, and the website will think I am you and allow me full access to your account. There are ways of managing this in a semi-secure way, but it needs to be done properly, which is explained in detail in the blog I linked to for the OP should they wish to go this route. If I misunderstood and the OP just wants to create a single session, not a persistent one, then he can ignore what I said. Edited May 21, 2017 by DulongC Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted May 21, 2017 Share Posted May 21, 2017 (edited) I'm still not sure if we're on the same page here. Yes, the OP wants to keep the user logged in, and, yes, he/she wants to use cookies for that. This is exactly what sessions do. It has nothing to do with “going beyond standard sessions”. In fact, even storing the user data directly in a cookie is valid and common practice, if the integrity of that data is cryptographically protected and the server rejects all manipulated sessions. Big applications sometimes use this to take the burden of session management away from the servers. I wouldn't recommend it to less experienced programmers, but it's one way of implementing sessions. You keep making this distinction between “standard sessions” and “persistent sessions”, but the only difference is that “persistent sessions” are supposed to run longer -- whatever that means. Technically, there are just sessions, and you may very well turn standard PHP sessions into “persistent” ones simply by increasing the time limit. Since the OP never even mentioned time, the whole persistence thing seems to be irrelevant. Yes, session cookies can be transferred from one machine to another, which is why the cookie needs to be protected through HTTPS and attributes like Secure and HttpOnly. But again, this is all standard stuff, nothing special. Some people try to bind the session to a particular IP address or user agent, but this is unrealiable (IP addresses are typically shared and reused) and can create lots of problems for legitimate users who simply cannot or don't want to keep the same IP address for a long time. Long story short: Cookie-based sessions are the standard solution, and there's nothing wrong with that as long as you use correct a implementation. I'll happily discuss security improvements, but right now, I'm more concerned about the basics. Of course we all agree that the original implementation of the OP is unacceptable. But this is the programmer's fault, not a problem of cookies. Edited May 21, 2017 by Jacques1 Quote Link to comment Share on other sites More sharing options...
sanjsimi Posted May 21, 2017 Author Share Posted May 21, 2017 @Jacques1 can you please explain me more about secure session or cookies and how to proper use them. I was always made login systems with session's and i wanted now to change it to cookies but its as i see now complicated same as a session. If i don't protect session i see on many pages and forums that session can be hijacked easy on http protocol or with javascript. I was storing only session random key and user id in 1 database table and when user come back on page i was checking query->user id->session random number if they exists and match with user session when he is on page. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted May 21, 2017 Share Posted May 21, 2017 Making PHP sessions secure If you have PHP 7 (which you should), a few parameters are different from what I wrote in 2013, but the basics are the same. Note that session security must also include protection against XSS and CSRF attacks. Otherwise an attacker can just make requests on behalf of another user without having to actually “steal” the session. So make sure you have proper HTML escaping and anti-CSRF tokens in place. Quote Link to comment Share on other sites More sharing options...
sanjsimi Posted May 22, 2017 Author Share Posted May 22, 2017 (edited) Thanks for the links and for explanation. I'm using PHP 7.1.1 at the moment on my localhost. Oh as i see those 3 settings are removed in PHP 7.0 session.entropy_file /dev/urandom session.entropy_length 16 session.hash_function sha256 Edited May 22, 2017 by sanjsimi Quote Link to comment Share on other sites More sharing options...
jay5r Posted May 22, 2017 Share Posted May 22, 2017 The short answer to the OP's question is, "No, your cookies are not secure because you're only passing the first three parameters to the setcookie function. The other parameters are really important and should not be ignored"… bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] ) $path – You'll probably want to set to '/' since you probably need your cookie available on all pages on your site. $domain – I'm not sure if you're using a subdomain, but set it to the most restrictive value possible (for maximum security). So 'www.yourdomain.com'. If you're not using a subdomain I've noticed the browsers implement things differently than the W3 spec. The spec says that '.yourdomain.com' and 'yourdomain.com' should act the same way (e.g. the cookie is available on all subdomains), but if your host name is yourdomain.com (e.g. no subdomain), then setting $domain to 'yourdomain.com' only sends it to that one host name. It's not available on other subdomains. To get all subdomans you'll need to set $domain to '.yourdomain.com'. $secure – should be set to true (or 1). That means the cookie will only be sent over encrypted, HTTPS connections. Which means your site needs to be encrypted. If it's not, stop now and get it encrypted and then revisit your cookie question. $httponly – should be set to true (or 1). That will stop it from being available to Javascript in standards compliant browsers. There are other things you can do to increase security (many of which are mentioned above), but you first need to start with using all the parameters in the setcookie command. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.