Is it secured to check if user is logged in with cookies? - php

On a website I am developing I am currently checking if a user is logged in if it's cookies are set. The thing is I'm using these information for some request on the database and allow him to do some tasks on the website. Though, it came to my mind that if the user edit its cookies, he might be able to be someone else (editing it's username/id). So, is there a way to secure it or do I have to use sessions ?

Yes, you can use cookies. You just need to make sure that the cookie provides data you can use to authenticate the user, and not a token that means the user is authenticated.
Bad cookie:
username=foo,logged_in=true
Good cookie:
token=uifhjrjf4093jf3904j90j390kf934j8438j0493jf9034
And then compare the authentication data against a datastore on the server.
Do I have to use sessions?
Sessions are a way to store temporary about a user (who may or may not be authenticated). They are a quick and easy way to solve part of the problem and not something that should cause reactions of Do I have to? :(.
Most session libraries use cookies to store the token that links the collection of data associated with a session to the browser to which the session belongs.

What I usually do is give a random hash in a cookie, then have point it to a database table in which I store the full browser string, a time to live, a last access time, the username and the hashed password (for comparison in case the user changes passwords because he was compromised, this will invalidate every other sessions except the one that changed his password).

Related

How to ensure malicious users won't change cookie value?

I'm developing a login page for a very small site, and for the "remember me button",
I use the user-id which then I encrypt before placing it in the cookie, and when i want to check if he already has a cookie, i uncrypt the value and connect with the user-id given.
But I'm sure that's not secured enough and people will just have to set a cookie with a random value with encrypting and this will make the job, isn't it ?
As solution to this could be to generate a random token, put it in cookie and in database. Then, if you have the token, you can connect.
If user get stolen this token, this is not the page problem isn't it ?
But I don't know how to process differently..
Anyone has a solution ?
To simply answer the asked question: You can't.
Cookies are stored on the users computer and with enough access rights and/or knowledge the user will be able to delete or modify any cookies your website set.
Encryption is taking information and make into non-sense so no one can access the information. If you need encryption is up to you. But I think this kind of session management is implemented already in a lot of ways. One of the simpler would be some kind of "dynamic API Token"-implementation - Storing some kind of Hash-like String in the cookie and in DB. If they match -> login, if not -> logout. (Symfony example: https://symfony.com/doc/current/security/custom_authenticator.html )
Another one would be JWT (JSON Web Tokens), these are indeed encrypted because they send information back and forth.
If you want to implement something like this yourself I would suggest to look at documentation about these two to start.

how to use remember me functionality with own unique device id's

In this age we have different machines, devices and phones, but sometimes we would like to be remembered by our own name.
I have a website where one person should be able to check "remember me" on the device he is currently working on, and having this working on all of your devices in the house.
Currently I was using a remember me function which creates a hashed key, saving it in the cookie, and in the database.
However - when logging in with the same user, but on an other device, the hashed key in the database is overwritten so the remember me function on the first device is down.
I was thinking to ceate a session table to hold the different sessions, (although it might hold different sessions for one user as well)
So Question:
How can I set/generate a unique session key for a device with php.
a browser fingerprint won't do as I use same browsers on different devices.
anyone ideas?
ofcourse I need a secure solution, preventing copying the cookie to another device or changing cookie information (from your user to admin) is important.
For a start having a hash key instead of a username does not add any extra security.
Just use a cookie with the username in it. The password is there for security.
I would do the session table to store all the sessions. Store the user's ID and the session ID in a cookie, that way when the user comes back, you can check to see if they are both in the table. If they are, they don't have to log back in.
The basic idea is to store the session ids from the different devices and tie them to one user. On the database level that means you don't have a "session_id" field in your user table but a separate table with "session_id" and "user_id" columns.
Please think about the security implications of session fixation and session hijacking. For a description of a more secure "remember me" system, read these articles:
http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
http://jaspan.com/improved_persistent_login_cookie_best_practice
ofcourse I need a secure solution, preventing copying the cookie to another device or changing cookie information (from your user to admin) is important.
Ultimately, this is solving the wrong problem.
The way to prevent this is to:
Use HTTPS everywhere.
Send all cookies over HTTPS, with the secure and httpOnly flags.
That's it. This is related to the problem of client authenticity. There are some techniques that can stop lazy attackers (e.g. user agent), but any of these techniques can be spoofed trivially.

Securely store the "logged in" status of a user

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.

Security in php session cookies

I am trying to understand security when it comes to session cookies in php. I've been reading a lot about it, but I still lack the specifics. I need the basics, someone to show examples.
For example: Do I place session_regenerate_id() before every session cookie? What more shall I think about. I am asking about specifics in code - examples if possible.
Thank you very much.
I am using 4 session cookies after logging in.
SESSION "site_logged_in" = true
SESSION "site_user_nr" = the number of the user to access user_table_nr
SESSION "site_user_id" = the user's id to use when changing data in tables
SESSION "site_user_name" = the name of the user to display on page
When I check if the user has access, I check if all 4 cookies are set, and if site_logged_in is set to true.
Are there better ways? Do I have the completely wrong idea about this? Can users easily be hacked?
In fact you need to have only one session in your website. When you call session_start() session is being created on server and user automatically gets session cookie. Think like session is a some sort of container that placed on the server, you can put whatever you want in that container. However session cookie is just a key to access that container on the server.
It means that you can safely put some data in the $_SESSION and only the user that have cookie with matching session id can read it.
About users being hacked. Yes they can be hacked as long as you don't use HTTPS connection, because cookies and all other data is being transferred in clear text, so if someone intercept users cookie he can access the data stored in the session.
Always use a security token for logging users. This security token could be generated by using crypt(). After logging users in, change the security token periodically until they log out. Also keep the server backup of all the session variables including the security token (in a database). This would also help you to track user login history.
One more personal suggestion: Never use any data from the database as session variables without encrypting it with any of the hashing functions or functions like crypt().
The session information is stored server-side. What you should check is that they're logged in, and that they exists/can log in (in case of deletions/bans).
As you're checking they exist/can log in, you can pull the other information from the database such as name, nr and so on. All you really need is a key called 'logged_in_user' or something that stores the ID of the logged in user. As Alex Amiryan said, the cookie can be copied, so you might also want to store the IP address of the last accessing view in the session, so you can try to ensure security.

What is the best way to securely authenticate a user ? (session, cookies, php, mysql)

What is the best way to securely authenticate a user ?
So far I was thinking of:
Generate a random $SALT for each successful login and store $logged = md5($hashed_password.$SALT) into database; delete on logout.
Store $logged into a cookie (If user checked "remember me"). Set $_SESSION['user'] = $logged;
On a visit: Check if $_SESSION['user'] is set; if not, check for cookie, if data doesn't match, redirect to login page.
What are the risks ?
The only issue I can see with your existing framework (which I like otherwise) is that there is the possibility of collision for $logged.
It is not mathematically impossible for two valid user log-ins to result in the same hash. So I would just make sure to start storing the User id or some other unique information in the Cookie as well.
You may also want to keep a timestamp of when the $logged was put in the DB, so that you can run cleaning queries where they are older than x days/weeks.
The first step is a bit overkill, as this is what $_SESSION['foo'] basically does client-side for the lifetime of the session. I'd just store a salted and hashed password for each user to begin with, salting with the date or other pseudo-random factors.
Setting the cookie might prove useless if the user clears their cookies, or the session expires. This will leave the user logged in (according to your database) when in reality they're not.
I'd stick to just $_SESSION['foo'] and cookies and leave the database out of the login process.
First No need of doing
Store $logged into a cookie (If user checked "remember me")
Starting the session should be the first thing you should do place session_start() on top of your index.php (file which gets executed) . This way a cookie name "phpsessid" gets created on user browser by default independent of weather user is logged in or not . value of this cookie is unique by which you can identify the user after he logs in. So you dont need to create any other cookie for this purpose.
In first point you have mentioned It create random SALT string when user logged in and clear it when user log out.
Main problem is you have to check SALT string is exist or not in each redirection of page. So it create heavy traffic in Database server.
Yes this is very useful for checkout user already logged in or not.
But in case of power failure in client machine after log in when Salt string remain in database after long time.
In second point to user authentication in cookie it is not secure. Client can easily show authentication cookie in browser
In third point to store authentication in session it means create session variable on server side and store it in file on server side. It is very secure then store it in cookie.
The best way to authentication is combine point number 1 and 3 which you mention.
You can check user already logged in form other pc or not?
You can easily clear SALT string if session is not exist.
You can easily manage Login in case of pc power failure
One problem I can see - your solution sounds annoying for people who load your site in multiple browsers at the same time.

Categories