I'm currently working on a little instant messaging project. So far everything has been going pretty well.
The only problem is security. When someone logs in, 2 cookies are set.
1) Name: loggedin; Value: {username}
2) Name: mvc; Value: {userSecretKey} <-- pretty useless
These are the cookies that I use so I can setup the next page. However, I believe there is a far better way to do this. And no, I don't want to use sessions because I have a "remember me" feature.
Someone could just set the cookies themselves and "sign in" without actually signing in.
What would be a better way to set this up? Maybe some sort of changing key?
I would suggest using PHP Sessions alongside cookies that are purely used for the remember me feature. You could set it up like this:
User logs in
You store the user IP and Useragent in the session
If remember me is enabled, create a new database entry with the user id, an unique random id + IP & useragent of user, then add a cookie that references the unique random ID.
Everytime you access the session, check that the request IP and Useragent match with the ones originally set in the session when the person logged in.
When the user returns after they close their browser, where only the remember me cookie is left, compare the request IP and Useragent to the one in the Database
If they match, log them back in automatically.
Users have fun.
Cheers!
You can still use PHP Sessions even with a 'Remember Me' function. You just need to set the cookie with the userid or username, and then, if they aren't logged in and the cookie exists, read their info from the cookie and log them in.
Have your logic that checks if the user is logged in check for an active session for logged in user. If it doesn't exist, redirect user to log in. In your login logic, check to see if the 'remember me' cookie is set. If it is, log the user in using the cookie. If the cookie doesn't exist, present a log in form.
for the security bit, you can use the secret key that get's reset when you log the user in. Would it be hijackable, yes, but if you keep changing the secret key/token the window for hijacking should be small.
Related
I have build a php website, you can enter your login information and it safes a authentication cookie in your browser. After that a SESSION variable called 'user' is created and you can continue to the user specific pages. My question is, when the user switches to another page for example his settings should i check his login information again(hash auth_token and compare it to the value in db) or is it enough just to check isset($_SESSION['user'])
Sessions are stored on your server, and cannot be directly accessed by the visitor of your website.
This means that if you make sure that, if $_SESSION['user'] can only be set when the visitor enters valid credentials, you don't need to check the cookie every time. You simply rely on the session cookie. Checking it cannot hurt though, so why not do it?
Note that it is possible for a hacker to copy the cookies and pretend to be someone they are not. This is called "cookie spoofing" or session hijacking. Erasing important cookies when an user leaves the website can already defend against that quite well.
You're being somewhat vague about what you store in the "authentication cookie", but I think you're using random tokens which you store in the database and link to an user. That's a good idea. It is important to generate a new token every time an user logs in, and let tokens expire after a certain period if they're not used.
Since php login application uses session id(one for each user) which is stored in cookie which is send as header information to server that allows the user to get automatically logged in(assuming that the user is already logged in some another tab in same browser lets say Chrome).
My question is if I store that user session id cookie information in another browser(lets say Firefox) and open the same application, will the user will get automatically logged in or not.
Or if someone finds out my session id and store them in its browser will the application will allow the user to login or not.
Take a look at session hijacking.
If somebody steals your session cookie, and you are still logged into the website, then yes. The attacker can log in using that session cookie.
And because of the answer given by #JonTan, you may see the fact that auto-login based only on PHP's session ID is not secure.
There all sort of solutions to that problem, but the base of each of them is to try and identify as many "unique" attributes of the user.
For example, store the user user-agent and ip address. When you "auto-login" the user, check for those details as well, and if they don't match than destroy the session. You may also add another token that you generate from this data as an "extra" security attribute and store it in the cookie, and check if that token match as well (you will most likely want to generate this token based on the user-agent, ip etc, so that you will be able to regnerate the token to match).
I have a website which has a login/logout feature. How can I ensure, 100%, also in a stable technique, that a user won't be a able to login to the same account from two different computers?
Javascript can't be used for this, since it's easy to disable it.
For example, .NET has a Session_End function that executes when a user aborts the connection with the server. How that can be done with PHP?
Thanks, Guy
Note: This technique would effectively logout the account on the first computer when logging in on a 2nd.
When a user logs in, log the session id for the user to the database or equivalent. On each page request, ensure the session id of the user matches the session id stored in the store for their account. Requests from a logged in account with a mismatched session id should be rejected and the user should be logged out.
It depends on how in depth you want to go. Most commonly:
Create a unique session id cookie on login and saved it in the database
All web pages check the session cookie to make sure it's valid
if the session isn't valid, the user is redirected to the login page
When another user tries to log in, it overwrites the previous session
This essentially kicks out the first user
Large companies will also store the IP address in the database as well (so session cookies can't be stolen)
I'm wondering what is happenning when a user logs in a website with or without checking a "stay logged in" checkbox.
From what I understand start_session creates a variable on the server and stores the session id on the client's browser in a cookie, destroyed when closing the said browser.
Following that reasoning, I guess that checking the "stay logged in" checkbox pushes back the expiration date by N seconds, which would be achieved by setting:
setcookie(session_name(), session_id(), time()+N);
In that case, I see no need to use cookies, at least for the logging process.
Am I right or awfully wrong? :)
There are a couple of typical ways a "stay logged in" box might be handled...
You could set the user's info in a persistent cookie, and look for that cookie.
You could create some unique ID (it better be a big one...like a GUID or a hash), store it in a persistent cookie, and let that serve as auth info.
Note that most solutions don't involve the user actually staying logged in; they just make it so that the user doesn't see another password prompt. Keeping the session alive and storing the session ID in a persistent cookie is technically possible, but for a site with a lot of users, that'd be quite a bit of extra space and load on the server.
The way I have written an option like that is to create a token and store it in the database along with the user ID. I then give that token to the browser as a cookie. Anytime a page request is done, I check to see first if the user has an active session, then if they have this token cookie. If they have a token cookie, I look into the database to see if it is valid and if so create a session with that user ID.
I'm sure this is an insecure, easily breached method, however.
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.