php storing user id in session? - php

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.

Related

Is using cookies instead of a session for storing username and password wrong?

I've started learning PHP by myself, and in the beginning, I would often choose the simplest way to do a task instead of the best way. Now that I'm developing important websites that need to be 100% secure, I hit this dillema,
I'm using cookies on my main page, to store the login session. Basically, the username and the hashed password is stored in a cookie and is loaded and checked against the database any time the user visits a mustbeloggedin page. For my main page, I'm using md5. Not because I want to, but because I have to. I know that poses a great security risk for the user because a keylog attack can basically freely take his password.
On this new website, I'm gonna use sha256, so that shouldn't be an issue.
Here's my question: what other security issues does storing this kind of data in a cookie and not in a session pose?
Here's mine:
Anyone with physical access to the computer can get the user's hash and store it for later use, by manually setting his cookie.
Any infected computer does the same as the above
Data is loaded, parsed, checked every load (not a security issue but still optimization-wise, it's not very good, but I don't mind that)
Anything else?
Does the domain variable inside the cookie make it secure enough not to be read by any other site?
Edit:: I'm also reading about someone intercepting the data being sent from a client to the server. How are sessions different than this? If I store a session , can't the identifier cookie still be hijacked and used by someone else? Would also adding an ip address to the cookie, then when validating the cookie, also check the IP address and if it's different then print the login form again help?
It seems you are trying to make some improvements, but not enough really.
There should never be a need to store passwords in a cookie, session, array, or anything else.
The password should be in the database and not be taken out to chance further access to it, or manipulation of the data holder in some way.
Otherwise, your highly secured database with hashes and salts on passwords, is only as secure as the framework/scripts and variable or cookie you store the password in (which is less secure than the aforementioned DB setup)!
From your comment:
Your question and statement makes no sense, you're describing a login
page and I'm describing about how the website knows you're logged in.
The cookie has the username and the hashed password, not plain text
password
So you store Bob's password in a cookie, with hash etc.
I steal Bob's password cookie. It's hashed, so safe right?
Ok, so I (James) use it on your site. How does you site know I am James, not Bob? It cannot.
It checks the cookie I stole, and password hash/salt/whatever you do match in your checks (otherwise it wouldn't for Bob either so would be useless).
It thinks I am Bob.
So now you start to check other things, if I have another cookie, perhaps username.
I have already stolen that.
So now your site looks at my cookies, sees a username and password, checks them, and says "welcome Bob, here's your personal/sensitive details, do as you wish...".
Passwords stay in the database!
You could try checking user agent, IP, and a load of other arguably less than useful/sometimes useful things etc, but these are things you can do "as well" as password+has+salt, and at the same time not store passwords in cookies or Sessions.
If your only methods to stop a hacker from using that stolen golden password cookie (hashed or not) is to check user agent, IP, and something else that can easily be faked, then your site is not secure.
Also, anytime the user needs to do something like change their password or email address, or check their whatever sensitive data on your site, you ask them to re-type their password.
Possibly resetting their cookies/hash/hash+salt stored in the DB, but depends on scenario really.
EDIT {
Use a cookie to store the Session reference, and any sensitive data in the Session.
Again, what you should store in the session depends on what data it is, if you run your own server, or shared, etc. Shared hosting can have bad config, opening up other security issues, even extending Session security issues.
(Info is in the links below - as said in comments, reading is your friend ATM - and then some evaluating and considerations of your specific needs)
}
Here is some serious reading for you:
First, your MD5 and even SHA256 are not secure:
http://php.net/manual/en/faq.passwords.php#faq.passwords.fasthash
Hashing algorithms such as MD5, SHA1 and SHA256 are designed to be
very fast and efficient. With modern techniques and computer
equipment, it has become trivial to "brute force" the output of these
algorithms, in order to determine the original input.
Because of how quickly a modern computer can "reverse" these hashing
algorithms, many security professionals strongly suggest against their
use for password hashing.
Also read the link for that quote - the bit about how you should hash, and the bit about salts.
Also, importantly, read about how to correctly store salts and hashes. There is a LOT of BAD advice out there which is misleading to the point you end up with barely any more security than if you just used MD5.
Storing the salt in the DB with the hashed password is fine, just also use unique salts etc (it's all there in the link, about mcrypt/blowfish etc)
A must read, even if you only take bits from it (and even if you ignore the rest of my answer):
The definitive guide to form-based website authentication
Faking Session/Cookies?
More reading:
What is the best way to prevent session hijacking?
Also read about:
Session fixation; Session sidejacking; Cross-site scripting;
And again, given you stated this:
Now that I'm developing important websites that need to be 100% secure
You should really spend a lot of time reading about all these things.
Cookie/session hijacking is real, and generally simple (script kiddie stuff).
If you want to produce secure websites and applications, you really need to learn about quite a few attack methods, preventions, etc.
Best way is read the links I've given, then any "branches" which stem from that read about them too.
Eventually you'll have a larger picture of the vast range of security concerns and resolves to them.
Some takeaways for cookies.
You want to limit any sensitive information saved within as it is not secure.
Cookies are perfect for session ids which you can then use to query your database and check if it is expired, matches an ip, matches user-agent and any other security/validation checks you want to do before you route to relogin or resume session.
http://php.net/manual/en/features.cookies.php
You mentioned user authentication. Most encryption protocols can be broken by using and md5 is considered 'broken' at this point due to completeness of lookup tables with all the hashes and the slight variations between hashes.
How can I make MD5 more secure? Or is it really necessary?
Salting your hash is crucial which adds another layer of security as is additional cdn/server restrictions to block/restrict brute force attacks:
https://crackstation.net/hashing-security.htm
http://www.cs.virginia.edu/~csadmin/gen_support/brute_force.php
If one is overly paranoid you can implement two factor authentication ( expensive? ):
https://isc.sans.edu/forums/diary/Implementing+two+Factor+Authentication+on+the+Cheap/9580/
http://www.twilio.com/docs/howto/two-factor-authentication
Don't store any credentials in cookies. There is session cookie and that is enough. In your database you can create a table where you will store PHP session ID together with user id. It is enough to check user's login and password once, at the logging, to establish a session.
I was doing the same as you do: storing login, password and session id in cookies and had many problems - occasionally for unknown reasons the browser was not deleting one of those cookies, or I had problems with paths of those cookies. I had to develop very complicated methodology for assuring that those cookies are properly set and that all of them are present in a given moment - I tinkered with removing and adding those cookies manually in the browser and had to come up with new ways of preventing the problems arising from such activities, but I was always able to make up new way of breaking that down and had to come up with new mechanism for preventing that.
All of this mess stopped when I finally decided to leave only one cookie - session ID, which I authenticate before every session_start() call - you can check if such a session exists and even compare current browser footprint with previously saved one. It is then very simple to foresee bad scenarios - when somebody deletes this cookie, session is over, garbage collection will clean it up. If somebody changes it or adds fake one - you can compare it against your sessions table and not start a session. To have better control over the sessions, use session_set_save_handler functionality.
There is a lot wrong with your chosen implementation.
the username and the hashed password is stored in a cookie
Don't do that. You should consider the content of cookies insecure.
and is loaded and checked against the database any time the user visits a mustbeloggedin page
There is no need to do that at all, if you know the user is already logged in (session).
I'm using md5
Using md5 at all precludes any semblance of security.
On this new website, I'm gonna use sha256
That will make almost no difference if credentials are still stored in a cookie.
So what should you do?
When a user authenticates themselves store their user info in the session. Any time you need to check if the current visitor has already authenticated check the session data. The session's data is stored on the server - it is secure. There's no need to call the db to find out who the user is on each page load, if the user's data is stored in the session.
Do not use cookies to store user credentials, especially if you're storing the password hash as stored in the db.
Don't use md5 - and if you're "forced" to do so change it at the very first opportunity.

php: using cookies / user authentification

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.

php optimising members after login

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.

PHP Login System

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.

Create unique Poll/vote/survey in php

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.

Categories