i'm looking for the optimal way for safe user authentification to my website.
i'm thinking about the following solution:
first login: asking for login data -> generating hashcode consisting of ip address, password and cookie expiration date -> storing that hashcode to database but also into a cookie.
next login: check for cookie, look for hashcode in my user database.
would that be the safest way? or will there be problems using cookies?
thanks
The best and easiest way is to use php-sessions.
<?php
session_start();
$_SESSION["user"] = "foo";
$_SESSION["ip"] = "123.132.123.132";
?>
Generally, you will want to store a cookie in the browser that points to a record in your database somewhere that says that he is a known user. The one thing you'll want to ensure is that that cookie id is globally unique. So, yes, using a hash (or md5, or sha1) on a variety of unique attributes would most likely be sufficient. Putting a unique on that column in your database would be a good idea as well.
Another idea would be to have a column in your users table for cookieid, generate that when the entry is created and ensure it's uniqueness. Then just use that every time when that user logs in. You could change all the values of that column for every user with a backend script every once in a while if you want to freshen up the cookies if you're really worried about security.
will there be problems using cookies?
Except for newer html5 features that aren't compatible with all browsers, cookies are really the only way to save login information. Go to a big site you use, ebay, amazon, wellsfargo. Wipe all of your cookies and private data, then go there and login. Then view your cookies. What do they put in there? If it's good enough for those guys, it's probably good enough for you.
Related
While creating my website i was stuck on a thing.
Wether i should use $_COOKIE or the session.
I thought using using $_COOKIE would be better.
But what should i store in cookie the users username or the user's unique id ?
And how much time forward i should put the time of the cookie ?
And should i forward the same time on each page or different ? If different then how much ?
It ultimately comes down to whether your website/application needs to be stateless or not. (See Webservices are stateless?). Its mostly a design decision, but I prefer stateless applications where possible.
If you do use cookies here are some tips:
You want to store data in the cookie that will uniquely identify the user, but something that is not able to be guessed.
It is common to put a user_id or a username (provided the user is unable to change it) and a random hash stored alongside the row in the database. When it comes to logging a user in load the user by their user_id and check that the hash in the cookie matches the one in the database.
As far as how long to store it for, that depends on the nature of your application. If it contains sensitive information then its probably not a good idea to make it last for a long time. You should update the time each time the users requests a page so if a user is using the site they will remain logged in for the duration of their visit.
It is really important not to put sensitive information in cookies, because they are stored in plain text on the user's computer.
You've not provided any information relating to the reasons for your choice of data substrate nor any indication of what you are trying to achieve ("php optimising members after login" - is meaningless gobbeldy-gook).
Wether i should use $_COOKIE or the session.
Hopw much data are you trying to store? For how long? Do you require to have access in the absence of a session? If so does the data need to be available? What is the impact of the user changing the data outwith your website?
But what should i store in cookie the users username or the user's unique id ?
Neither - if your site believes the assertion in the cookies, then hacking your site is as simple as changing the cookie value.
I am wondering what the risks are of storing the userid in a session?
then simply doing a
if(isset($_SESSION['user_id'])){
login_user($_SESSION['user_id]);
}
Are sessions encrypted enough that we wont have to worry about hashing them?
What are the chances of someone being able to change their ID?
The session is by default stored in /tmp as a file. It is not viewable by the end user unless you have security issues such as directory traversal vulnerabilities.
The only portion the client sees is the unique hash stored in a cookie which maps to the relevant session on the server.
Most applications use $_SESSION as you are. If there where a wide spread weakness then major projects would be doing things differently.
Storing a user id in $_SESSION is a reasonably common practice.
Your alternative could be to store the session information (including current user id) in a table using the session_id() in some form, as the key.
Session information is stored as plain text.
Dependant on your setup, the session location should be safe on a properly setup server. It is possible to change the location with session_save_path() which will overcome potential location issues.
If some one can access your session, he can, probably, access much much more. I would not hash it and also make sure it does not get to the client
I would advise against adding only the user id to the session. For example:
1: Create an account in one browser and log in. Then leave that browser open and go to another computer.
2: Log into the same account and delete it. Now make a new account with a different password (with the same username, if that is used as the id).
3: Go back to your other computer and do stuff. You will find that you could quite possibly now be using the account made on the other computer.
Basically, since the session stores the id this may not necessarily still belong to the same person depending on iff accounts have changed etc. And if no password is required (since you already went though that process when you owned the account) then it is similar to breaking in.
So this seems to only have a chance of working if, when you delete user accounts from the database, numeric ids can be reused (about 2% of the systems I have seen do this). Or if the user id is the username (about 20% I have seen do this).
So I would instead suggest adding the userid and the password hash (i.e md5, sha1) to the session and obtain the user information using both of them each time.
I'm creating a login system in PHP, and I want to know how to best protect the user information string in my cookie. I was thinking of encrypting the string with a key somehow? Is this the best way? I'm kinda new to this.
Thanks in advance.
Don't store sensitive information in cookies. Store a session ID hash to connect the logged in user with their account.
Aaron Harun has the right answer for you. There's basically no need to encrypt such data as long as you store it in a session, because that data never reaches the client/browser/user, as it is all server-side. When you create a session on PHP, it handles the cookie stuff for you, so you don't have to worry about that. In most cases, there is no need to deal with cookies. In security, dealing with cookies is detrimental.
I've seen some sloppy sites that actually store the username in a hidden field on a form, which allows anybody to simply edit their local copy of that form and take actions as whichever user they like. This seems like an obvious problem, but cookies are no better.
If you truly think it's a good idea to design a homebrew authentication system, you need to design the database first. Don't store plaintext passwords, store a hash instead (like md5, sha-1, etc) and at that point there's no harm in generating a salt for each password (a random string that you append to the user's password before hashing it, and store that salt with the password hash because you'll need it later--this prevents dictionary hash attacks, ie rainbow tables).
You should never store secure information in a cookie. Cookies are saved in textformat on the user computer, and there are many reason why you should never stock sensitive informations in them :
Cookies are basically text files, which can be opened by anyone on the computer, with any text editor.
The cookies are stored on the user computer, this mean he have no time limit, no connection limit, no processing limit, so he can try to brute force any data as much as he want without being worried of getting ip banned/kicked...
You should only stock things like a username to remember or a session id.
If you absolutely MUST store information in a cookie instead of the user's session, consider signing it with HMAC. The hash_hmac function is a builtin in modern PHP versions.
If you're storing a user login for a "remember me" feature, store both the user's ID and a hash of information that is only available in your database. For example, hashing together the login name and password and storing that with the user's ID in the cookie is reasonably secure. If the user ever changes their password, all the machines he's logged in to with that method would be invalidated, and there's no way to simply change the ID in the cookie and still get logged in, because the username/password hash won't match.
You get sessions for free! That is data stored server side, automatically handled by PHP/framework-of-your-choice. You just put data into the session, which is associated with a random UID stored in clients' sessions. On the clients' side, this is the session cookie. This ID is automatically generated, you can fine grain the behavior manually.
Data stored client side is never safe, no real encryption available. Sessions you will need anyhow for keep track of logged in users. If you have lots of data, you can use the ID to identify associated data from other datastores (DB, XML etc.)
I've been told that it is insecure to store things such as passwords, usernames, and user ID's in cookies, and that instead you should store a sessionID in a cookie. Here's where I get lost.
My objective is to have a basic 'remember me' feature. Normally I would store user login information in a cookie, but as this is unsafe, I'm wondering what the alternative is. I understand that each time I create a session it creates a cookie which creates a unique ID, but expires when I close my browser. So how do I get access to this session information after the browser has closed?
All help is appreciated.
Possibly the best approach, as has been suggested and what most third-party apps do, is to create a "user_sessions" database table with the following fields:
session_id (var_char)
user_id (int)
ip_address (var_char)
last_logged_in (unix timestamp)
Then use a cookie to store an md5 hash of whatever you like, possibly:
md5($username.$ip); //since md5 has a lot of reverse look ups now you should use a number of fields to validate. You could use a different crypto function to make it more difficult to crack, but md5 is the simplest version available in all php versions.
EDIT: You will then compare the stored hash from the cookie with the database session_id to see if they have already logged in. The reason to combine a couple of fields in the md5 function is to create a less "guessable" hashing format. It makes it less likely someone will be able to edit a cookie and login as someone else.
This could be done for all users (this way you can track who is online) and just set a "persistant" login variable in the cookie. eg.
p_login=true || p_login=false
That way you'll know whether to auto login or force login.
note: You may be able to look at http://www.openwall.com/articles/PHP-Users-Passwords for a different way to hash passwords, session_ids and users.
This could be a fairly steep learning curve. Have you considered using a pre-existing CMS or other solution for what you're wanting to achieve, or even a framework that might include this functionality?
For a 'remember me' feature you can send out cookies containing the user ID and a hash of that user's hashed password hashed again with some known, but secret, token. That solution doesn't allow you to remotely expire someone's login, however, without resetting someone's password.
Another approach therefore is to generate a unique token for that person's login and have another database table relating that unique token to a particular user and expiry date.
The unique poll/vote/survey i mean here is, user can only vote once. How do i do that? Track their ip? Login? Beside login, what else? (login is my last option, thus beside login, is there anything else I can do?)
To restrict the number of votes per person, you need to track the person.
Now there can be several ways to do that, and I'll list them with their pros and cons. Its for you to decide which method suits you best.
login: this will offer you ultimate control. But its also a little cumbersome for the user. and its your last preference
IP: how will you handle people behind web proxies? How about people with dialup connections and/or dynamic IPs?
cookies: this is good for short term polls, so you can set the expiration of cookies to a time when the poll has ended. But, a potential drawback is that a user (contrasted with a luser) will know how to delete the cookies!
openId: While this method is not too different from the 'login' method, this saves the user from registration (which really is the part that sux the most about logins).
EDIT: the problem with this situation is that you need to resolve the identity of the user. I think OpenID does this pretty darn well.
Cheers,
jrh.
You could always store a cookie on their computer. Beware, though, that the user can easily disable cookies, or modify the contents of a cookie. There is no 100% reliable method to do what you want to do - the user can always create a new account, or move to another computer, etc.
If you want to go with the cookie approach though, there are three possibilities.
You can store a bit of text saying this person has already voted
You can store a unique id referencing their vote
You can store a session cookie and store the rest of the data on the server (probably more secure, since they can't edit the data, only the session id, and doing so will probably invalidate it).
The most secure way is a login system.
But if you dont want to use one, i used to add a hash containing the users IP and browser witch will help me filter out to a much better degree then just simple IP ( the browser string might be different for different persons using the same browser, because of the version, operating system and extensions installed ), but you still have problems if they switch browsers, the same problem as cookie.
The hash was stored in a database.