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.
Related
This is the use case:
a hacker login to a web site private pages of another user ("the correct user") using his/her pw
the correct user, without logging-in, changes its password using the "forget password" function
the hacker never log out and his session stay on because he still has the credential as a session data in his browser
What I would like to do is this: once the correct user changes his/her pw the session of the hacker is destroyed by the reset password user function. But the correct user browser has not any reference to the session id/code of the hacker ones so if it is run the function session_destroy() this does not affect the hacker session, just the correct user one. But, since some unique ids linked to the user account are set as session data, it is theoretically possible to identify the session having that field valorized to the correct user id and erase the session itself. The problem is how to do it, does Codeigniter have any function to find a session saved on the server searching for its field values? Currently, I use the default way to keep track of the sessions, so on disk.
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.
My login system currently works as follows:
Grab the user's username and password from a POST form.
Check the username and salted + hashed password against the database.
If authentication is successful, generate a long, random, alphanumeric string.
Store this string in MySQL, as well as in a $_SESSION variable along with the username.
This is opposed to just putting the user's password in $_SESSION. I feel like that's leaving the door wide open for spyware to come in and steal the user's credentials.
On each page that requires authentication (e.g. non-sensitive account settings, members-only areas, etc.), check the $_SESSION username and string against those stored in MySQL.
If they match, go ahead and show the page. Otherwise, show a login form.(?)
When the user explicitly logs out, remove the random strings from MySQL and $_SESSION.
What I'm stuck on is how to handle when the user implicitly logs out. That is, when he/she closes the browser window without hitting any "log out" button on the site. I'm pretty sure I still need to remove the random string from MySQL, so someone can't use a stolen cookie to log in afterwards. But how do I know when the user closes the browser window?
("Remember me" functionality is irrelevant for now.)
How Should I Implement Login Sessions?
Authentication and session management are 2 different things, although they are closely tied together, you seem to be talking about authorization too.
If authentication is successful, generate a long, random, alphanumeric string.
Why? PHP already generates a random identifier (the session id). If you want to differentiate between authenticated/non-authenticated users and/or identify which user owns the current session, just store the username / userid in the session.
putting the user's password in a $_SESSION variable
Why would you ever want to do that - once you've authenticated the user, you never need to use the password again.
check the $_SESSION username and string against those stored in MySQL
Why? How can the session data be changed other than via your code? If you suspect that your serverside code could be tampered with then it doesn't matter what you do, the system will be insecure.
When the user explicitly logs out
...you explicitly destroy the session. That's all.
When you remove the redundancies from your proposition there is no need to clean up after an implicit logout.
BTW: there are a number of security issues you have not addressed in your proposal, notably regenerating the session id after an authentication attempt.
You could use an ajax call on onclose event to kill the session... never tried it but it should work:
$(window).unload( function () {
// ajax to kill the session
} );
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.
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.