views:

73

answers:

6

I have set up a login system that checks a mysql db validating username,hashed password, and a banned column (0 means not banned and is the default value, 1 means banned). if there banned they obviously cannot loggin.

The problem is i'm new to php and having a hell of a time trying to figure out how to log out a user who is currently logged in. As it stands now my cookie will last for 2weeks, and even if i ban a user, their session will stay active thus they will have acess for 2weeks or less.

How can i force a user to reauthenticate, without penalizing the masses.

A: 

If you are storing the session data in a database, delete the row with their session information. Or, delete the file if using files. Then next page load, the login system shouldnt be able to verify their login information (since there's no info for that session), and prompt them to re-login.

GrandmasterB
A: 

maybe you want to store the sessions in another table and delete it when you ban the user.

you know. check the table every time the user load a session and if the user isnt there. delete the cookie and destroy the session (sending him to the index of your site)

Freaktor
A: 

You can store the userID in the session and on each request, you check if he's banned (SQL query). If true, you destroy his session so he's forced to reauthenticate. Which fails of course because he's banned.

sled
+3  A: 

Your server knows what cookie is associated with each user. Why not just delete that cookie from its "current sessions" table?

If the cookie is just "username, who is logged in", you have a real problem, because instead of a magic number, the cookie contains real information, and it becomes trivial to forge. Then a malicious user could simply create a cookie saying "I am [admin], and I am logged in", and that's obviously a much larger problem. So if you can't just delete the session cookie from the "known cookies" table to solve this problem, you have a bigger problem to worry about.

Kistaro Windrider
Ya, i figured i was doing something wrong. Didn't even think about storing session info in a separate table...I guess i have some more research to do, because if the session info is checked via mysql the original question seems way easier to answer.
scotty
Yikes! Glad it got pointed out to you, then. An important guideline for interactive web site design is to "assume that you will be lied to": the client can say whatever it wants to say to your server. It can send any message with any content at any time. But it doesn't know things you haven't told anybody. How can your server defend itself against getting lied to by someone trying to break into your system?
Kistaro Windrider
I really appreciate the help. Just to make sure i approach this the correct way. Once i set up the "cookie table" every secure page should query the mysql database and see if a) the user is valid, not a spoofer, and b) the user is not banned. something like http://www.devarticles.com/c/a/PHP/User-identification-using-cookies-in-PHP-MySQL/1/
scotty
That's a reasonable approach. Be aware of the downside of the strategy suggested in that article, though: a user can only log in from one computer at a time, or the rotating cookie will go out of sync and log them out. You don't need to re-query the "is banned" column every time the "active session cookies" table is hit, though- just delete the cookie for the user when he's banned, and he'll be logged out because the cookie won't be found, and the new login will fail.
Kistaro Windrider
Thanks alot for your help.
scotty
+1  A: 

If you are doing your authentication system completely on your own (kudos on that, BTW) you merely need to unset the session value that contains their authenticated status. So, if you used:

<?php
session_start();
if(isset($_SESSION['isloggedin']) && isBannedUser())
{
    session_unset(); 
    session_destroy();
} 
?>

The pseudo-code above calls to a fictitious function called isBannedUser() to determine if they are banned or not. If they are, in my example above I call session_unset() to unset all values stored within the $_SESSION and then session_destroy() to completely close the session. Some would probably argue that you may not need to unset if you're destroying, but I have just gotten into the habit of cleaning up all variables and values that I make in code.

This should be in every page so that you check if they're banned as frequently as possible. With the $_SESSION destroyed the user is, effectively, kicked out of any part of your website that requires authentication. You will need to implement supporting code in your login workflow that keeps a banned user from logging back in.

Hope this is helpful.

Liam
Ya i'm doing it by myself..your code makes perfect sense. Right now i'm just checking info on login and not any session data. never thought of storing it in a table.
scotty
A: 

On a file-based sessions system, maintain a counter somewhere which triggers a periodic check of the database for updates, something like:

<?php
    session_start();
    $_SESSION['hits_since_last_verification']++;

    if ($_SESSION['hits_since_last_verification'] > 100) {
       $banished = ... // get banishment flag from database
       if ($banished) {
           $_SESSION['loggedIn'] = FALSE;
       }
    }
?>

and then decide how long you'd like a banned user to be allowed to continue poking around the site until the session data is refreshed and they get booted.

Another option is an external script which runs through the session storage directory, loads each in turn, checks if the user's banned, and updates the session file as appropriate. But this would be painful on even a moderately busy system as you open/unserialize/check banishment/update/reserialize potentially thousands of session files every X minutes.

Marc B