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

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.

Related

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.

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

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).

OpenID sign in mechanism - Stay signed in

I'm developing a website in PHP and I'm trying to use OpenID for log-in mechanism. I want a behaviour similar to StackOverflow's. By that, I mean whenever I open stackoverflow, I'm already signed in. I found two related questions on StackOverflow:
OpenId + remember me / staying logged in
Sign in with Twitter, and stay signed in (PHP)
I understand that I should sign in the user and if this is his/her first time, I should sign up the user and set a cookie in his/her system. However what I want to know is what should I store in the cookie? Username/password combination? That seems like a security issue. And the other question is where should I check for the cookie? I would appreciate a simple tutorial/code sample. Thank you.
This is basic web app session management with cookies and OpenID doesn't make a difference here at first.
No, absolutely do not store the username and password in the cookie. Cookies act as "bearer tokens", meaning whoever has the cookie gets in. The best thing to store in a cookie is an unguessable and arbitrary key that you can use to look up real information in a table in your application. So, the user shows up with a cookie of "myappsession" and a value of "234871nb341adf" tied to your domain. Your app would then look up the value of "234871nb341adf" in a local data store and see if it's tied to a valid user. You'd be best served to also check how long ago that user was there and whatnot. If it's a valid session and it's within your time and usage limits, the user is logged in automatically.
For extra paranoia from the RP side, you can make use of the checkid_immediate mode of OpenID to make a background call to see if the user is still logged in to their IdP. If they're not, then you at least know which provider to try to send them to for re-validation and can provide a better user experience.
If you want your site to be really secure, you should do all of your sessions over HTTPS and tag your cookies as both "Secure" and "HTTPOnly", which is documented on the setcookie function manual page: http://php.net/manual/en/function.setcookie.php

Codeigniter/PHP sessions security question

I'm developing a web application using Codeigniter. When a user authenticates with my site I'm currently storing their 'user-identifier' in my session cookie (which I have enabled encryption on). Several of my model classes use the value in 'user-identifier' parameter of the session/cookie to make changes to properties of user accounts.
My concern is that I'm wondering if it's possible for someone to take a valid codeigniter-session cookie with a user-identifier that I've set, change the user-identifier's value to the value of a different user, and make changes to another user's account. Would codeigniter/php sessions create an error if someone attempted to change a property of a session cookie?
Open your /application/config/config.php, locate "sess_use_database" and change it to "TRUE" if you haven't already. This way all session variables will be stored in a database table and session cookie will only contain session id string.
For added security, you can also change "sess_match_ip" to TRUE. This way if someone steals your user's cookie and tries to pass it as their own, session will be destroyed.
"if
it's possible to take a
valid codeigniter-session cookie
change the user-identifier's value to
the value of a different user, and
make changes to another user's
account."
My answer is not really CI related, so please bear that in mind.
When you auth the user "username1" what should be sent back to the client, for auth purposes, should be a hash that the server correlates to that user. All communication between the client and the server will rely on that hash.
The server will generate a unique hash per user and the hash should have a short time to live. Can someone capture a hash and pass as that user? Certainly. That's why you should also check for the user's Agent and IP to check if they match the hash in order to prevent session hijacking.
NEVER DO THIS:
If seen some new developers storing the username in a cookie and reliing on that client sent variable to update their databases. Never do this. Do not ever, ever trust the client. When the server gets the client's hash it should check if it belongs to an authenticated user and grab the user_id (variable to update the user data) from the server. NEVER from the client.
I'm not sure what your "user identifier" is exactly. The general rule is, don't store anything in the session cookie but the session ID. Store everything else (like a user ID) internally on server side, and retrieve it using the session ID.
If the user changes the session ID (which is a random string), a new session will start. The idea behind the session ID is that it's impossible to guess other user's IDs - that's why it's random, and so long.

What should I store in cookies to implement "Remember me" during user login

I have a login system in place for my website, the details of the user which are stored in the database are userid(unique for every user and identifier), email address(unique), display name(not unique), password and membersince.
Now what should I store in the cookies? I was thinking about storing just the userid in the cookie with an expiration date and then if the user revisits my website after signing up check for the cookie and log him in( which kind of doesn't look right to me) and destroy the cookie if he decides to log out.
*A little explanation would also be very helpful. Thanks
You can only ever store the userid in a cookie if you sign it with a secret key that only your applications knows. Otherwise it's possible for the user to change the cookie to anything and login as somebody else. So, if you want to store the userid, store also a hash of the user id with the secret key (ideally using HMAC) and when you want to log them in, calculate the same hash and compare it to the hash from the cookie. Another solution is to generate a random token, store it in the database and use that in the cookie. If it's long and random enough, there is very little chance somebody would guess another person's token.
PHP has built-in session management that does exactly what you're looking for:
http://us.php.net/manual/en/book.session.php
I wouldn't recommend storing the user_id in the cookie. Instead, you can generate a unique token and associate the token with users in your database, and check & regenerate the token on each request. Again, this is a bit redundant, because session management is already built into PHP.
PHP' $_SESSION does this for you. You can even write your own session class if you like full control.
A small tutorial is found here:
http://www.tizag.com/phpT/phpsessions.php
Here is a small example to use mysql to store sessions instead of php default (files in /tmp):
http://www.hawkee.com/snippet/2018/
Simply add the cookie expires to 2 days or the number of days you want to remember the user and save the cookie.

Categories