PHP Redis session handler multi user - php

Lets say we have a user, he logs in and browses the site like usual. Then we have lets say... the brother of this user and he wan'ts to login to the same account from a different ip or a different browser. Is it possible to check if redis has a current active session and deny access for this very reason to prevent multilogin for the same user?

First, what does your question have to do with both php and node.js tags? In which one did you tried to implement your case?
Secondly, whatever the environment might be, what is stored into Redis depends on what you decide to store besides the session data. Usually session data stores a random sessionid and a userid associated to it. Nevertheless, in some cases you can chose to associate a session to a user than has not yet authenticated, therefore storing a session without any user associated to it.
Preventing concurrent user access from different IPs has more to do with the authentication mechanism, rather than session logic.
One approach for preventing concurrent logins from different IP address is to save a map of active users like <userid, ip>. Then after you check the credentials, you also check that map to see if the user is active from a different IP address. In that case you can deny the authentication.
This solution also implies some clean-up mechanism for users that do not safely logout, which is very similar to the session clean-up (time_to_live). To take advance of the existing implementation, you can add an IP address field to the session storage along with the userid at authentication using the same logic for authentication as previously described. The session will now look like <sessionid, userid, ip>. It's just a way to piggyback on the session storage and take advantage of it's clean-up process.

Related

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.

eCommerce session data persistence

I'm currently building a shopping cart for an eCommerce site and am wondering about the best way to persist user data in the session during the checkout process.
The user flow works is as follows:
shopping cart -> login/register -> select delivery address -> confirm -> pay
My issue is once a user is logged in, I want to display a list of their delivery addresses so they can select one. The easiest way to do this is querying the model by the user's id, but my concern is for security - my first thought was to store the user id in the session and then use this to retrieve the addresses. However there's nothing to stop another user potentially hijacking this id (just by guessing random numbers) and revealing addresses for other users. I could perhaps use their email address, but this too could potentially be guessed. Is my best bet to use a combination of the two, or is there a better way?
PHP has built-in session capability. It loads a unique cookie to the browser and allows you to keep all session data on the server-side via the $_SESSION array. The cookie ID is unique for the session, not the user, so it changes each time the user signs in (if the cookie has expired). If you conduct the session in https, it's very secure. Without https, the session is vulnerable to someone with the (special) knowledge and inclination to intercept the cookie data, though such an interception is not easy. Depending on how secure you want to be, running without https may or may not be acceptable for you.
You can read more about PHP session capability here:
http://php.net/manual/en/features.sessions.php

How to make an authenticated user persist using a cookie

I am making a registration/login system with php. I think I have all the initial login stuff worked out(hashing password with salt, store in db...).
My question is in regard to keeping a user logged in between pages after their initial login. The way I understand it is that one method is to have a table of sessions on your server that stores a random unique id for each user and to store that id in a cookie on the user's computer. This way for each page they load all you do is lookup their session id in your database.
What I don't understand is how is that is secure? Couldn't somebody just sniff the ID and then fake being that user. Someone could even just try guess IDs.
I also read that it is better if the ID changes on each page visit. How does this increase security? It seems it just would decrease the amount of time any ID could be used.
Also how would any of this change with a "Remember Me" feature that would be stored for long time?
The ID you are describing is precisely what the session ID is, except it's handled for you transparently by php (browsers pass along this session ID with the cookie).
The security flaw you are describing is precisely what firesheep takes advantage of. You can prevent the session ID from being sniffed by making sure that all authenticated requests to your site take place over ssl. This not only includes logging in, it also includes any time an authenticated user tries to access a page (which means the browser will be passing along an authenticated session id).
If a user tries to access a page not via SSL, you should ideally redirect them to an SSL page and give them a new session ID, because the old one could have been compromised.
The key to such a system is that you don't randomly generate the key--you generate it using facts about the user, ones that another client wouldn't have knowledge of--like the user's IP address, user-agent, and session id. Then you make the user authenticate using that key and their session id (which is transparently handled by PHP).

Ensure web app access from a single computer per user

I have developed a web application in PHP for a client. The client is now renting out access to the system to another company on a per user basis.
Is there a way to prevent the secondary company to use a single login and give it to 20 people to use at the same time? I know one can get the IP address of the client machine that is being logged in from, but this is obviously not very reliable method. The answer probably lies in a combination of cookies and tracking things in a database, but my brain gets a bit stuck thinking on how to implement a strategy here.
Create a unique session ID when a user logs in and store that in the DB. Add something to the session authentication code (run on all page visits) that checks that the user's session ID is equal to the one in the DB and if not, log them out. Then your web app will be accessible by only one user at a time.
To be completely honest though, can't you raise this issue with your client?
No way to tell if the login is shared among 20 people. You can restrict access by blocking simultaneous usage thru session cookies.
Most of all, protect yourself with a published Terms and Conditions document. Violation of which - revokes any standing agreement/contract. And sue them if you can provide evidence (logs) that they violated it.
Make sure you bind one user to one session. In that way you can generate a warning screen if somebody uses the same login with another session. You can then let the user choose to close the other session.
In that way you can make sure two users are not using the system at the same time. It's a bit like a software program you have installed on a computer: multiple users can use it, but only one at a time. This is probably fine.
If you don't want that, you should try to bind the login more firmly to the user: make sure he logs in with a personal e-mail address, and he gets notifications (if applicable) via e-mail. Also let the user set personal configurations. In that way you create extra value for users to have their own account.
If you have a login you have authentication, and you write any user id in session, make sure that only one session with this id created, if the session already exists throw error message.
The only problem you will have in case and user did not logout properly, instead of it pressing x button on browser then he will not be able to login till session s not expired.

When setting users' preferences, is it best to use cookies as to session? (PHP)

For each user, I want to allow them to choose their preferences, such as which categories to show on their profile, which tags they want to see, etc. Would cookies be better than sessions because they don't expire when users logoff?
I think the best solution is to mix cookies and database - the last one for logged in users.
Cookies are fine, because the user doesn't have to log in on your website to have some preferences saved.
But if somebody will login to your page than you got ability to save his preferences in more stable source - server database. Then these preferences are available from every computer and won't disappear after "browser cleaning".
EDIT:
Don't use sessions - they are worse than both, cookies-based and database-based solution.
Why sessions aren't a good idea? First of all they rely on cookies (session id which required for proper work of sessions system is stored in cookie called SID/SESSID/SESSIONID (in most cases)) so whenever you clean cookies you also lose your session. Moreover session are available only for few minutes (from first page load to browser close or about 20 minutes of inactivity on website) while cookies may be available for few months or even years!
So how should you do that?
There are two scenarios:
When user is not logged in:
Then when he change some preference store it just in cookie
When user is logged in:
Then when he change some preference just save it in database:
INSERT INTO preference (user_id, key, value) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE value = ?;
That's example for MySQL but you can do this the same in others RDBMS.
And how do you get final preferences?
// That's VERY unsafe code... you HAVE TO do necessary validation (this is only an example)
$preferences = unserialize($_COOKIES['preferences']);
if (/* user is logged in */) {
$databasesPreferences = result_of_query('SELECT key, value FROM preference WHERE user_id = ?');
$preferences = array_merge($preferences, $databasesPreferences);
}
Sumary
This solution gives you the most stable way for handling user preferences for both logged-in and non-logged-in users.
Cookies can have an expiration date. If there is no sensitive data in them then they're fine to use, however if you're storing thing like user id's, etc. that will be used in queries you're best off using sessions as they're stored on the server where people can't manually get at them.
You generally have three choices of where to save user preferences:
database
cookies
session
When deciding between these, each solution offers different behaviors in terms of:
persistence
locality (tied to a browser or account)
security
If you need longer-term persistence of these value, you should put them in the database. If you want them to not require a sign in, then cookies are a better choice. There really is no one right answer-- it depends on what you're trying to accomplish.
What is the point of using cookies when the user has logged off??? User needs to be using the website in order to read from the cookie and apply the settings. Once the user has logged in, you may query the database and store the options in sessions until the user has logged off.
My recommendation is that it's best that you use sessions as they are much safer.
Cookies are nice because they can last between visits or "sessions". However they are also user editable and readable globally. Storing sensitive data like a login, password, session id, etc can lead to a malicious site hijacking the session or users information. Also a crafty user could alter the cookie to change the privilege level or user who is logged in and impersonate them.
Sessions are very secure because they are stored server side away from the prying eyes of users and other web sites. They do have the limitation that anything that's stored in them disappears once the session ends.
When I do login systems I prefer to use a sessions. You can pull the user from the database and then load various user defined settings into the session.

Categories