What values should store in cookie? - php

I have a table and have two column for username and password. I want to store a cookie for remember user's login. So what field should i use? I'm getting confused about storing username in the cookie. Because someone can try to log via rewrite a fake cookie. What should i do?

You should never store their username and password in a cookie. For a good example on how to handle this, see: "Keep Me Logged In" - the best approach

You should store a random, unique session id since users can tamper with cookies. PHP's session feature already does that for you - and you can store any kind of data in there since the data itself is stored on the server and only the session id is stored on the client.
Another option would be using a cryptographic signature to ensure the cookie hasn't been tampered with.

Related

Bcrypt 'remember me' cookie value

I'm using Bcrypt as shown in https://stackoverflow.com/a/6337021/999516 to store passwords in the database and i'm trying to add the 'remember me' feature to keep users logged with cookies.
When a user logs in succesfully, i re-create the hash and update it in the DB. If the user has checked the remember option, i create a cookie with USER_ID, expiration and now i don't understand: which value must i store in the cookie? the complete char(60) hash?
I would recommend implementing a separate "remembrance" hash to store in the cookie, with a corresponding DB table associating that hash to a specific user ID and expiry. Storing the actual user ID in the cookie is a Really Bad Idea since you have no way of verifying that they didn't just change the user ID stored in the cookie. By storing a completely separate hash in the cookie, you can easily lookup which user it belongs to in your DB table and auto-log them back in if it's valid and unmodified.

PHP & MySQL username storage and cookie

How to securely store usernames in database, without adding them directly to cookie value?
Example:
I want to display username of logged user.
If he have closed his browser early the only way to do this is $_COOKIE['cookie name']
where cookie value links with username in database.
So I don' t need to hash username.
Is it right? And if it's right, is it secure?
It is secure. Just do not store the password on the client (browser). Also never send the password to the browser.
You can store the username in the cookie, this is safe as long as you do not save the password there.
You can also save there user id, then it does not give away any of the authentication details while letting you find the correct user.
Use sessions. data stored in $_SESSION is stored on server, not on client.
The below is assuming you are talking about a persistent login feature using cookies. For the purpose of just remembering the user name (but not signing them in automatically), having a username in the cookie (optionally encoded) should be okay though. Regardless, passwords should never be in the cookie.
Cookies should NOT be directly identifying, i.e. user ids / names should not appear in the cookie. Instead, you should assign a sufficiently long enough string with random data to the users in your table and store that in the cookie value. Once used you should update the string and issue another cookie.
For example:
john | ewojroj1234ojqewor
jack | ljqwelkn1k31n23k33
The second column will be placed in the cookie. Later you will query that value against the user table and:
fetch the user data and store inside a session
regenerate the random string
issue another cookie
Password changes and signing out should also cause a change in the user token string.
For further reading, Barry Jaspan wrote a good article on this approach.
The best way to do it is to store only the user_id (the uniquely identifying primary key) of the user table in the $_COOKIE or $_SESSION variable - perhaps in $_COOKIE['user_id'].
Then on each page load, you can use that id to retrieve any user information you wish from the database. For example (Note this is conceptual/psuedo-code only. You would of course sanitize/clean/validate/bind the $_COOKIE or $_SESSION data parameter first):
SELECT * FROM user_table WHERE user_id = $_COOKIE['user_id']

Storing login information in Cookies

I want to save user's authentication information in browser cookie for persistent login. As they say, its never safe to store any secret info (such as password) in cookie, but in order to have an option such as 'Remember Password', i think there is no any other choice.
So, if a user want to remember his login info, and if i store username (Email) + Not the password, but some other unique info, such as HASHED DB ID in the cookie. Then i should check if the hashed ID stored in cookie matches with user's email which is stored in Cookie.
As I think anyone can very easily see the cookies stored in Browser (for example in Firefox, Options -> Cookies ).
So would this be as weak as for someone to read the cookie from the computer where its saved, then on other computer set cookie with that information and he would be logged in? (As the script will check the stored email and hashed id with database and it will match)?
Could this approach be bit improved without storing other information in database (such as session id etc) ?
Thanks
There is another option.
For each user, upon logging in and requesting to be remembered, create a long random string.
Store this string, along with the userId, in the cookie you give to the user.
Store a properly salted hash of the string in your db.
If the user presents a remember-me cookie, match the random string to the hashed verifier you have in your database (just as if it where a password).
If it matches -> log the user in and create a new remember-me cookie for them.
If doen't match -> request username and password.
I wrote an answer to the same question in How to improve my user login scheme - have a look there.
I would suggest using an unique key on the server to encrypt the username (in this case, email) and store it in the auth cookie. If the cookie is tampered it will fail to be decrpted and result in login failure.
If an auth cookie is copied (by manually setting the cookie or by XSS) to another computer (or another browser), then the user would be logged in as well on the new computer. You could consider adding some unique information about the computer (such as IP address) to reduce such risk.
This is an explaination about auth cookies in .NET, but I think the concept works on php as well:
http://support.microsoft.com/kb/910443
There is a good article on how to make "remember me" cookies more secure.
I have implemented the method described in the article in a PHP library: https://github.com/gbirke/rememberme, maybe you can use that as a reference.
Session fixation and cookie stealing is a real problem in the age of Firesheep. The only defense against that is securing your site with SSL and monitoring for XSS flaws.
Another way to improve your security is to remember if a user logged in with a "remember me" cookie and force him to reauthenticate when he does something "dangerous" like ordering or changing login credentials.
For more resources, see this Question: The definitive guide to form-based website authentication
you don't have so much of a choice when it comes to store user info on client side...
You can try to make some encryption using the client IP as the key.
This way even if the cookie is copied to the hacker computer and if he doesn't notice that the IP is the key of the encryption you'll have some descent protection of user's info.
Facebook is doing something this way, proof is everytime you try to log in from another connection point you have to go throught the user verification system...
So look for some reversible encryption and this should make your day ;)
You could also install a cookie with a UserID and a SessionID with a expire timestamp.
Then if you bind the cookie to IP or hostname (or preferrably both) you're quite safe from cookie stealers and other stuff.
i think there is no any other choice
Think again.
You don't need to store the password clientside in order to maintain a session. The 'remember me' operation is just the same - use a random value which is a lookup key to data held on your server.
Short of using client side certificates with pass phrases, anything else you do to complicate things will not improve security, and is more likely to expose your customer's private data.

PHP login security

This is how I'm building a login system:
Login:
Check username and password supplied by user with the database.
If username and password is correct, store only user ID in session, something like:
$_SESSION['userid']=$userid;
If User has checked the option to stay logged in, then set 2 cookies, 1 with userID and other hashed string.
To check if user is logged in:
Check if Session exists, the user is logged. is it ok?
If session does not exist, check if both cookies, userID and hashed string exist.
If Both cookies exist, validate them.
As the Session is stored in the server, is it secure to store only userID ? Can a user pretend to be other user and store his userID in the session and log in as him?
Thanks.
Yes, this method is very insecure. I can sniff traffic, intercept your cookies, and your system will accept me as an authenticated user. You are making the assumption that if you get a cookie with a userid and the hashed string, then that user is the same person that originally authenticated to create the cookie. That is a poor assumption, because cookies travel in plain text (unless you encrypt them), so as long as I can grab a cookie, I can pretend be whoever sent that cookie, and your system doesn't know any better.
Edit:
If you are going to use unencrypted cookies, why not just store the session_id in a database table? That way, at least someone that gets hold of a cookie won't have a valid username. Create a sessions table, and when someone successfully authenticates add a row with their user_id and the session_id. Each time a page is loaded, check to see if the session_id in the cookie matches a row in the sessions table. If yes, you can assume the associated user_id is the authenticated user. This approach is just as secure as the one you suggested (i.e. not very), but it's less complex and doesn't give away valid usernames.
Yes it's possible and very extended, this kind of attacks are called Session fixation and in your system (as David said) anyone who sniff your traffic, or have access to the user's drive and steal his cookies, may supplant a logged user.
The best protection is, of course, SSL, but if you can't use it in your website there are other things that can prevent (but not fully protect against) this attacks:
Save info about the user in the server-side when he login, good candidates for this are the IP and the user agent, but any other data that don't change in the entire session can be valid.
You can regenerate the session ID in every request, with this if the session ID is leaked the attacker must use it before the real user do any other request, but beware because every time the session ID is regenerated (in PHP at least) the user's session data is rewited, so this can be expensive if you have a lot of users or if you save many data of every user (this means that, if you're saving the session data in a file, the file will be deleted, created, and writed again).
Well, right now I can only think in these two, it's not much but at least you will put an extra complication to the attackers.
One more thing, don't trust the user's cookies, they can be changed by the user (or the attacker) at any time, treat it like any other user input.
PD.: Sorry for my horrible english, I'm truly trying to improve it ^_^
you could add an ip that the user id should belong to (in your database), that adds a little extra security - it might not always be the best solution
Yes it is ok to check if the session exists and also check that the user id is greater than zero.
The 'remember me' function is subject to sniffing as it's not over ssl, however that is how 'remember me' functionality is done.
Assuming this is happening via SSL, my biggest concern is your first step:
Check username and password supplied by user with the database.
You should be hashing passwords, and comparing the hash of the user-supplied password against the previously hashed password stored in your database.
You also don't have to worry about storing only the user ID in the session array; the session is stored server-side and is as secure as the rest of your server.
One potential problem is that everything is being stored in cookies. If someone somehow manages to get their hands on the Session ID, then they've also got the username and hashed string.
Chris Shiflett suggests creating some kind of fingerprint from the User-Agent string, or some other regular header, and storing it in a GET variable.
One way to bump up security is to have everything sent over SSL. Any time any kind of potential information is sent or received (such as the Session ID in a cookie), make it encrypted - not just the login form.
It is mostly correct but I don't agree with the cookie-option. This way if someone gets the two cookies can move them to a different computer and still use them.
The "remain logged in" function should be restricted to that computer. A possible solution is that if the user wishes to remain logged in you set the lifetime of the session to 1 week or so. Also you have to store the user's IP address, User-Agent and possibly X-FORWARDED-FOR header, and check them on every pageload against the stored values.

What should I store in cookies to implement "Remember me" during user login

I have a login system in place for my website, the details of the user which are stored in the database are userid(unique for every user and identifier), email address(unique), display name(not unique), password and membersince.
Now what should I store in the cookies? I was thinking about storing just the userid in the cookie with an expiration date and then if the user revisits my website after signing up check for the cookie and log him in( which kind of doesn't look right to me) and destroy the cookie if he decides to log out.
*A little explanation would also be very helpful. Thanks
You can only ever store the userid in a cookie if you sign it with a secret key that only your applications knows. Otherwise it's possible for the user to change the cookie to anything and login as somebody else. So, if you want to store the userid, store also a hash of the user id with the secret key (ideally using HMAC) and when you want to log them in, calculate the same hash and compare it to the hash from the cookie. Another solution is to generate a random token, store it in the database and use that in the cookie. If it's long and random enough, there is very little chance somebody would guess another person's token.
PHP has built-in session management that does exactly what you're looking for:
http://us.php.net/manual/en/book.session.php
I wouldn't recommend storing the user_id in the cookie. Instead, you can generate a unique token and associate the token with users in your database, and check & regenerate the token on each request. Again, this is a bit redundant, because session management is already built into PHP.
PHP' $_SESSION does this for you. You can even write your own session class if you like full control.
A small tutorial is found here:
http://www.tizag.com/phpT/phpsessions.php
Here is a small example to use mysql to store sessions instead of php default (files in /tmp):
http://www.hawkee.com/snippet/2018/
Simply add the cookie expires to 2 days or the number of days you want to remember the user and save the cookie.

Categories