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.
Related
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.
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 usually hang out in a community that uses a bulletin board software.
I was looking at what this software saves as cookie in my browser.
As you can see it saves 6 cookies. Amongst them, what I consider to be important for authentification are:
ngisessionhash: hash of the current session
ngipassword: hash (not the plain password probably) of the password
ngiuserid: user's id
Those are my assumptions of course. I don't know for sure if ngilastactivity and ngilastvisit are used for the same reason.
My question is: why use all these cookie for authentication? My guess would be that maybe generating a session hash would be to easy so using the hashedpassword and userid adds security but what about cookie spoofing? I'm basically leaving on the client all fundamental informations.
What do you think?
UPDATE #1
The contents of these cookies are what I think they contains. I'm not sure about it.
Of course if call a cookie ngivbpassword and contains an hash, my guess is hashedpassword. Probably it could be password+salt.
My main concern is about these solution giving to much information when under a cookie spoofing attack.
UPDATE #2
This question doesn't want to criticize the way these specific software works but, thorugh these answers I want just to learn more about securing software in a web environment.
This happens because session and login cookies may have different lifecycles.
Imagine website with millions of users every day. The website won't store your session for a year just to log you back the next time you get back.
They use login cookies for that.
These cookies are also called Remember-Me cookies.
Sessions are not persistent. Cookies are.
Update #1: I haven't worked with vBullettin but it looks like the classical "Remember me" feature.
Update #2:
Yeah, it's a remember me feature, I'm
asking why they're doing it in that
way
Alright... How do you implement a "Remember me" feature? You obviously need to use cookies, I assume that's clear. Now, what do you store?
The naivest way is to store user and password in clear text and perform regular authentication. It's among the most insecure mechanisms you can use yet some sites actually do it that way.
Second slightly less naive way is to store a hash of the user and password and perform a modified version of the regular authentication. Is not as bad as the previous method but it still suffers from some issues; for instance, there's no effective way to disable or expire a saved cookie from the server.
Third way is to keep a database table with "remembered" sessions, identify each one with a long unique string and store such string in the cookie. The string can be random or calculated but, of course, randomness has the advantage that the string cannot be guessed even if you know the algorithm.
Further security can be accomplishes by storing dates, IP addresses and other piece of data in the server.
As I said, I know nothing about vBulleting but it seems they're using method 2 or method 3.
Update #3:
The contents of these cookies are what
I think they contains. I'm not sure
about it. Of course if call a cookie
ngivbpassword and contains an hash, my
guess is hashedpassword. Probably it
could be password+salt.[...] My main
concern is about these solution giving
to much information when under a
cookie spoofing attack.
A successfully cookie spoofing allows you to fully impersonate the user so you can just enter the control panel and enjoy the free buffet, thus making the cookie content irrelevant.
Whether they store a salted password or it's just a name it's something I don't know.
Here is a question, what are your concerns? Are you building some kind of authentication system?
I also think that having the user id and password in cookies can be a security issue.
is user id encoded or an integer?
Cookies should be as-small-as-they-can peace of information about who you are on the server.
Sessionhash, session_id or sid is unique ID of you (your session on the server). The rest of cookies can be easily hidden on the server side.
Holding password hash in cookies is a security issue. You should avoid that.
Last 4 cookies comes from google ads.
PS. Most bulletin boards are not so great software anyway.
When a user logins I get him/her's ID and save it in a session var. What I wonder is, is this the way to go? Or should I use cookies? so it automatically login and so on.
session_start();
ifcorrectlogin {
$_SESSION['id'] = mysql_result($loginQuery, 0, 'user_id');
}
how do you authenticate your users?
//Newbie
Yes, this is the way to go. The session itself is already backed by a cookie to remove you any programming efforts around that. The session (actually, the cookie) will live as long as the user has the browser instance open or until the session times out at the server side because the user didn't visit the site for a certain time (usually around 30 minutes).
On login, just put the obtained User in the $_SESSION. On every request on the restricted pages you just check if the logged-in User is available in the $_SESSION and handle the request accordingly, i.e. continue with it or redirect to a login or error page. On logout, just remove the User from the $_SESSION.
If you want to add a Remember me on this computer option, then you'll need to add another cookie yourself which lives longer than the session. You only need to ensure that you generate a long, unique and hard-to-guess value for the cookie, otherwise it's too easy to hack. Look how PHP did it by checking the cookie with the name phpsessionid in your webbrowser.
Cookies can be manipulated very easily. Manage login/logout with Sessions. If you want, you can store the users emailaddress/username in a cookie, and fill the username box for them the next time they visit after the present session has expired.
I would try to find a session engine so you don't have to deal with the misc. security issues that bite you in the ass if you do the slightest thing wrong. I use django which has a session engine built in. I'm not aware of the other offerings in the field although I would assume most frameworks would have one.
The way they did it in django was by placing a cryptographic hash in the user's cookies that gets updated every page view and saving all other session information in a database on your server to prevent user tampering and security issues.
As BalusC mentions, the session_-functions in php are the way to go, your basic idea is sound. But there are still many different realisations, some of them have their pitfalls.
For example, as Jonathan Samson explains, using cookies can result in security holes.
My PHP is a bit rusty, but I remember that the session_-functions can also use session IDs that are encoded in URLs. (There was also an option to have this automatically added to all local links (as GET) and form targets (as POST). But that was not without risks, either.) One way to prevent session hijacking by copying the SID is to remember the IP address and compare it for any request that comes with a valid session ID to to IP that sent this request.
As you can see, the underlying method is only the start, there are many more things to consider. The recommendation by SapphireSun is therefore something to be considered: By using a well tested library, you can gain a good level of security, without using valuable development time for developing your own session system. I would recommend this approach for any system that you want to deploy in the real world.
OTOH, if you want to learn about PHP sessions and security issues, you should definitely do it yourself, if only to understand how not to do it ;-)
I am creating a login system for a web application using PHP. My question is, is it safe to only store the user login information in the current session? For example, if a user named John logs in successfully to my site, can I just store $_SESSION['Username'] = 'John' and $_SESSION['LoggedIn'] = 1 then check that $_SESSION['LoggedIn'] is equal to 1 on each page to verify the user is actually logged in? Or is there a better way to do this? I am not aware of any problems this may cause off the top of my head, but I wanted to make sure I wasn't leaving a big hole in my site that would cause problems down the road.
Also, I am storing an md5 hash of the user's password + salt in the database, not their actual string password so that is one less thing to worry about.
Let me know if you need any more information or if this is not clear. Thanks!
That's a perfectly reasonable approach. Your visitors will never be able to edit the session data on your server (unless the server itself is insecure, in which case anything's fair game), so a LoggedIn=1 value in the session is perfectly safe.
However, do keep in mind the risk that one visitor hijacks the session of another (by stealing the session key). One way to help protect against this is to also store the visitor's IP address (from $_SERVER['REMOTE_ADDR']) in the session and then in later requests confirm that it hasn't changed.
There are a number of risks to consider:
Session hijacking: this is where someone steals the user's cookie and pretends to be them. Some will suggest IP filtering to counter this but that can have awkward side effects. People use Websites from mobile devices or on laptops that are used at work, home and at wifi hotspots and there are other cases where IP addresses can change. So my advice is only do this for highly sensitive Websites (eg online banking);
Your Site is Compromised: in this case the user will have access to your database anyway so there is no extra risk with storing authentication information in the session. They can just as easily change who they are by issuing UPDATE statements to your database;
A Co-Hosted Site is Compromised: if you use shared hosting, a completely unrelated site could put you at risk (with or without this scheme) because a bunch of sites are all running on the same Apache instance and can thus access each other's files (although it can be hard to figure out what site they belong to). So if a site you've never heard of is hacked it can impact your site;
A Co-Hosted Site is Malicious: similar to (3) except the threat is internal but is otherwise similar.
So I'd say it's fine (subject to (2)) but just be aware of the risks. Follow, at a minimum, these best practices:
Never store unencrypted passwords;
Use a strong hashing algorithm (SHA1 preferred or MD5 at least);
Make sure authentication cookies expire at some point. How long depends on your site. It could be a week or two or an hour or two of inactivity or both.
Consider SHA1 or an even stronger hash instead of MD5. You're salting it, though, that's good.
Back to your question: yes, that's fine. However, implement measures to make sure sessions are not hijacked. Wikipedia actually has a fairly good article on it.
In most of the systems I've written, I've included logic to verify the remote IP hasn't changed. You can store that in the session, too, since the session vars don't get passed to the user (only the session ID). If you really want to get creative, you can add other checks -- user-agent, and what not.
You also have to account for session attacks. Check referrers. If you have a disastrous operation, let's call it a POST to DeleteMyAccount, I can write a form submission plus javascript to hit DeleteMyAccount in a forum post on an unrelated site, counting on that session to be present in the user's information.
Sounds OK; you may want to think about setting an expiry time (so if someone walks away and leaves the browser open they're not in too much danger).
On the whole, you are definitely on the right track. I would recommend you use IDs for your users in the session rather than the username as IDs are a better unique reference inside your code.
Also, md5 is not considered strong enough for password hashing anymore: it's is too fast to hash and you don't want that in a check that an attacker will need to run over and over again (whilst a real user only needs to do it once). I wish I could find the reference, but leading edge wisdom is to do lots of rounds of a leading edge hashing algorithm, like sha512.
You can use COOKIE instead of SESSION variable. you may set COOKIE by following
setcookie('ID', $variable, time()+8*60*60);
You have to be aware about SQL Injection. When you Insert or Update your database where user textbox relates please be aware about SQL Injection. Insert / Update your values by htmlentities() function.