I use php-sessions to check if users are logged in to my app. Is it significantly better for performance than just keeping the user id in a session and checking against the database if the user is logged in instead?
If the password changes or I want to block/log out a user it is easy to just change the database record, but when it lives in a session, can I do that? How?
You can use both.
Use the session variable as a first check, so that you immediately reject any request where the session variable is not set. This saves doing a costly database check for random door-knocking requests.
But if it's set, you still have to do a database check to see if the user's login session is still valid. When a user logs in, create a random token and store it in a session variable and the database. When processing a new request, check if the session variable matches what's in the DB. If an admin wants to force a user to be logged out, they simply invalidate this database record.
I use php-sessions to check if users are logged in to my app
I'm not sure exactly what that looks like - but it sounds horrendous. Either you've broken the session security model or you must be brute-forcing the session data every time you want to find out whom is logged in. Certainly a requirement to maintain a list of active sessions and user identifiers would be best implemented piggy-backed on a custom session handler (for the purposes of triggering - not for a common storage substrate) but you seem to be implying that you you are not doing this.
If the password changes
You cannot keep the password used to authenticate the session in the session.
Related
I think that I figure dout how to do this:
When my user connect, after checking if he has the good username/password, a session key (a random long string) is created and put inside the DB. The same session_key is put inside the session.
If the user get out of my app without login off, when he comes back, if his session_key match one in the DB, the user is O.K and will connect as the user that have that session_key. If not, the session is closed, the user is rerouted to login. If there's no problem, a new session_key is created (to replace the old one).
I think it would be O.K., except for 2 things:
-How can I make the session_key disappear from DB after a certain time? I guess I should execute some code on the server, but how can I execute code on the server if nobody is using my app for a certain moment?
-If it's just the session_key, is it alright to use the cookie insted?
-Is it O.K. to just check if there's a session_key in the DB that correspond to the session_key in the session, or should I use something else to be sure? I will generate a random long string and crypt it the same way I do with password, so i think it will be secured enough and that it wouldn't be likely that the session_key be identical.
-insteed of using the username to get data from the DB, would it be O.K. to use the session_key (getStuffBySessionKey())?
What if my user access the cookie and change the username?
There's no need to store the username in the cookie. The cookie should only have the session key info. You'll get the username from that via db query when the user attempts to login. If the user changes the session key value in their cookie, then it will no longer match an active session in the database, and they will have to log back in. It's essentially the same as clearing the cookie.
In addition to the username and the session_key, I will put the user privileges in the cookie. I will need it to know if the user is admin, creator or visitor.
These should be stored in the database as well, not in a cookie.
Is there an other way to check if the user didn't try to change anything WHILE he still is on the app?
Nope, you should be checking for a valid, active session on every request from the user. If there's no session cookie, or if the cookie doesn't match a valid session, redirect them to the login page.
As others have pointed out, you'd be wise to use PHP's built-in sessions for all this.
I am using PHP and Codeigniter to do this. Currently I am just saving a cookie to the user with their username and a $logged_in variable set to true. Then when they try to access a page, I check for the status of their $logged_in, and if they are, they're free to access.
It occurs to me that this may not be the safest way to go about this. Is there a better tactic I should be using?
It's not safe at all. Cookie is considered user input and it can't be trusted in any case.
Use sessions instead.
Also you could use some sort of custom login encrypted code (I'd personally suggest SHA1) that is matched against the login code in the database and is refreshed every, let's say, 5 minutes.
CodeIgniter offers a nice solution to this problem - You can use Database Sessions.
With Database Sessions, all the data you put in a session is stored within your SQL database. The user gets a cookie with a unique session ID that changes on a regular basis. The session ID along with IP and User Agent is used to match up the user with their session data, thus making it impossible for users to tamper with their own session data, and very hard for them to hijack someone else's session.
You can read more about CodeIgniter Database Sessions in the CodeIgniter User Guide.
So on my application login form I've got one of those little boxes like [_]remember me
When the user checks that we set $_COOKIE['rememberMe'] with the value of the username. Now when that user comes back 3 days later, I obviously want to recognize them and re-log them in automatically. It doesn't sound safe to simply check for the existence of that cookie and then use it's value as the username to login without a password. But I'm not sure how else I would log them automatically... Is there a way this usually done?
Your cookie should have three values:
1. username
2. expiration time
3. a session code
When a user logs in, generate a session code and set an expiration time.
Store that session code and expiration time in the cookie and on your database.
Then whenever user returns to the site, and if user is not logged in:
1. check for the cookie
2. check for the cookie against the database
If all three variable matches and the expiration time is not over, log the user in.
Alternatively, if you simply encode the session code as say a md5 of ($username.$expiration_time), then you won't have to set up a database for storing and checking. Although having a database with randomly generated session code is much safer.
This is extremely unsafe. Since the cookie is the only thing you have to go by and the cookie is transferable from system to system, you would be vulnerable to cookie poisoning attacks and cookie copying attacks. If this is indeed the course you're set on, you will need to use some manner of foot-printing the user's system and storing that information in a database somewhere possibly as part of a persistent session on a session state server. This information could then be compared with the new login so if the cookie is transferred to a different system, it will not match and the automatic login will fail. As for accomplishing the login, I would recommend at a minimum to have a session state database where session information could be stored per session ID and username. If these 2 items are stored in the cookie, this information could then be used to get the information out of the database, and the foot-printing could be used as a stop-gap (although a very weak one) to prevent misuse.
The only information you need to store in a cookie is some unique hash that's going to point to the right user session in your system. Storing username or other information is redundant and unsafe considering the fact that username can be captured by an attacker and used with a combination of other information. To make the system more safe, you should implement a layer that'd check user's location by the IP address and his browser details. I suggest you should learn from what companies like Facebook and Google do with user accounts.
Place a random and uniqe hash in the cookie and store it in DB too with the current client's IP address.
If the user comes back, you can search for the hash in your DB.
Is it safe to store a password in a sessions variable?
For example, usage would be in a form which is submitted to itself.
For example a change classifieds page, where users first enter a password, and then if pass=ok, show the form to change the classified. All on same php-page.
But Whenever a picture is uploaded in the "change" part of the php page, the form must submit to itself again.
Should I here use the stores Session password to verify that the user is actually the user, and that it is secure?
In other words, is it safe to store something like this:
if($pass==$row['password']){ // If password was correct
$_SESSION['pass_ok']='1';
}
Thanks
Camran, what you are trying to do is a standard way to maintain php sessions. You are actually not storing the password in the session rather just storing the information that this particuar user has already logged in.
$_SESSION['pass_ok']='1';
On every page you just have to do a session_start() and check of this session is already set to 1, if yes they assume him to be logged and proceeed, else redirect to login page.
If someone gets hold of the session id then they definitely can access the user session. You can do a few things to make it more secure.
Use SSl (https), it will make hard to sniff the data and get your session id
maintain the client ip in the session when user logs in, for every request after logging in, check if the requests are coming from same ip
Set a short session timeout, so that if left idle for a while the session times out automatically.
Use a pre-built authentication system. That your best bet at being secure because they would have (or should have) thought of everything (security issue) already.
What i do is,
Check user logs in correctly
Assign a session to username + userLOGGEDIN session
When a page is clicked, my system searches the DB for username + userLOGGEDIN if its true then allows access to the page, but what it also does is, deletes the record its just searched for, and inserts a new record for the username + userLOGGEDIN with a different MD5 HASH. So hopefully it will be harder to crack.
I would advise against it. If someone logs in and copies the session ID down they can theoretically log in to any page. I would instead advise you check the password is okay on every page refresh as this will be more secure.
Additionally, always store passwords hashed in a database, or better yet, hashed with salts.
how do you check if a user already has logged in?
so that if a user in another browser cant log in with the same account.
also, is this a good solution or should i let the user log in in the other browser and then log out the current user and display a message (you are logged in from another location) just like messenger does?
Using sessions is a good way to do this, and is a very common method for controlling authentication.
The flow usually looks something like this:
User visits site, and session_start() is called. A unique session identifier is set for that visitor (ie. a cookie).
User submits his login credentials to a login form
Login credentials are verified, and this fact is stored in the session data with $_SESSION['logged_in'] = true, or something similar
For the rest of the user's time on the site, you can check $_SESSION['logged_in'] to see if the user has logged in.
In order to control a user's logins, you could simply have a field in a database (users table is fine) indicating what the current session id is (retrieved with session_id()) for the user, and if it doesn't match the cookie value you just received, then you immediately call session_destroy() for that id, and consider the user as logged out.
Using $_SESSION means you don't have to worry about generating your own tokens, and gives you the power of the built-in superglobals to facilitate storing information about the user's authentication status.
Personally, I would allow multiple sessions to be active for a user for most web sites, as there's usually not a good reason not to, but it obviously depends on the nature of the site. However, storing the current active session id as mentioned above is a pretty simple way to accomplish this.
Generate a random token upon signing in (or use the sessionid), and store this in the database and in the users cookie. With each page access, ensure that the users token matches the database entry. If the two don't match, alert the user that they've logged in elsewhere.
You could also store the login time, which subsequently would be the time the token was assigned, and require 30 minutes before permitting another user to login with the same ID.
The first half of the question was answered well with how to detect the multiple users but how to treat them I think still needs a bit of work.
First if a user logs in correctly let them in, don't prevent them if they are logged on some other place. If you really don't want the user to have two open sessions then log out the old one or simply update the session id that you are saving so you can bounce out the old connection. You can inform if you want but I would only message the session that you invalidated. If you message the user logging in it becomes annoying when you are only dealing with the case of a user switching computers and they forgot to log out of the old session.
Well All solutions mentioned above will work but if on every page access you are making a call to database and checking for the session token to see weather its the same token assigned to user .. will kill your response time. what i'll suggest is use a caching mechanism instead of database in above said solutions. storing session token into database will add extra field to your database which is actually not required. Use open source caching solution like memcache.
you can make a table like userLoginStatus with fields like clockIn time & clockOut time,
and insert current time in clockIn when user is do login, leave clockOut time blank at that time, it should be updated only when user do clock over logout button,
so you can check specific user's current status, where clockOut is empty that user should be logged in. because it updated only when user do logout.