Check permissions? - php

How do people usually verify that the information being fetched from a database is indeed related to the active user?
For example: let's say we list a group of PMs inside user x's inbox - how do I make sure that only user x can fetch something from the inbox, and not someone else (this would be done by "hacking" the address ofcourse).
Obviously I could just compare the active username with what is in the database table, but is there no easy way I can control this globally somehow, without having to compare the active username with hundreds of different tables for different actions?

Supposedly you're fetching the messages of the logged in user to begin with, no? Something like:
"SELECT * FROM `messages` WHERE `recipient` = '$loggedInUserId'"
If so, I don't understand the question. If that's not what you're doing, you're doing something wrong.

Well your application tracks users sessions, and ensures security. I.e. when user logins server sets cookie with session id, and by session variable your server upon request of page will know what user is really requesting something(or maybe no logged in user at all if there is no cookie), thus your application may use user id from session and request url to figure out if it should show what is requested, or show error message or redirect because user is trying to access what is not his. Of course this is a bit more involving but thats a start. I suggest reading on php sessions and cookies.

That is what database query conditionals are for... only selecting the relative data.
Generally once the person is logged in you would get their username and password from $_SESSION variables, query the database to make sure they are a valid user, then grab whatever you need using a WHERE username = '$username'

Related

How to get mysql database updates to trigger re-authentication in PHP sessions

When starting a session, an authentication is made to the database through a query. If this authentication is granted, one or more session variables are filled with data. This allows the user to transfer through multiple pages without having to re-authenticate - which is great. However, if a session variable that is being used is changed within the database, i.e. username change, access privileges change, the changes are not rippled through to the session (obviously).
How is it possible to get the database changes to trigger, or ripple to, the PHP session variables.
An example is being logged into a website where you have access privileges x that allows you to access pages 1,2,3. Your privileges are now taken away for some reason and you now have access privileges y which allows you to only access page 1. If the user is already authenticated within the site, these changes will not affect the users current session, and will still be able to access pages 2 and 3. This could be an issue in many situations.
Currently my solution to the problem is to re-authenticate the user every page, and update the session variables accordingly. This definitively seems the wrong way to accomplish this task from my limited understanding of how sessions (should) work.
Essentially, I would like a way for database updates to trigger a re-authenticate of the current logged in user. i.e. if user john12 has his database row altered, then his session should require re-authentication.
At the moment I can't think of any way to accomplish this without querying the database every time a page is loaded.
Any tips or solutions would be greatly appreciated.
How I usually do it is by having 4 fields for authentication is my database.
Username
Password (usually hashed)
Token
Logged IP
I remember the user's auth data in cookies. When user has entered the right username and password the website generates a new token and sets two cookies - username and token. On every page load you check if the username, token and logged IP match (to prevent token steal).If one of them isn't right remove all of them and redirect to login page.
In your case if you want to relogin on password change just delete the token when it has been changed.
The only con here is that only one machine can be logged at a given time.
I don't see why you don't want to query the database for user permissions, SQL databases are incredibly fast even with lots of records especially if searching by primary key.

Avoiding multiple logins to an account from different locations

I want to restrict multiple logins of the same user from different locations. How can I identify a user's multiple logins from different locations in the same/recent times? I think some flags and IP checking in a table might be a possible solution, but are there any better solutions?
Update:
I think the session or cookie might help if it for a single machine. Like when users log in for the first time create an activation key and store it, and every other time when users login to that machine, check the cookie value. likewise.
I would resolve something like that by making in user table, a activeKey column. Everytime user is logging in the activeKey is changed ( simple way subchar(md5(time().$username), 0, 16)), and and store it in session. Every time the webpage is refreshed/entered key would be checked. If dosn't match then logout with info. On correct logout key would be set to NULL, so when it could give a flag.
This metod could be combined with IP address, but only IP address could be cheated, same with MAC, and so on.
That is a main idea. There could be additional data like last login date, IP last login date, and so on.
You can have a table containing the IDs and the IP addresses of the users that are currently logged in. Just check against this table everytime someone logs in.
Here's a solution that doesn't require constant database access to work...
(which will avoid the requirement to check the session_id() against the database value every time you request/refresh a page, relieving db/server stress)...
1. On login, grab the pre-existing session_id stored in the DB for this user and do this:
session_id("the pre-existing session id in the database goes here");
session_start();
session_destroy();
2. Then start a new session and save this new session_id to the database, overwriting the previous one. This will logout the previous session on this user if there is one active (effectively logging out the other guy using this account).
Give it a try and let me know if that does the trick!!
NOTE: This is "in theory" as I haven't yet tried it. It's based on this accepted stackoverflow answer. And you should probably manually create the session_id based on something unique to each user, that way you don't wipe out a session that someone else is using that happened to be the same as the session last used by the user you are doing a check for.
I think, just have extra 2 columns for each user - "LastLoginTime" and "IPAddress" in your Users table. If the duration is too short and IPAddress vary then you can give a warning to the user. Additionally you can also inform the City & Country from which the user is logged in.
I would add in the users table an ipAddress column, a LastLogin date column, LogStatus column with boolean values (actually MySQL uses 1/0 for boolean) to check if the user is logged in or not, a Country column (although this could be bypassed by using proxy), and a blockedStatus column, again with 1/0 values, that would check if the user is blocked or not.
Then at log in page, you'd check if the user is logged in then he can't login, if he was recently logged in, and the country is different, then something is happening and you would need to block the account and send a email with a link to unblock the account if the legitimate user was the one logging in.

How to secure this PHP form

I have a form for editing users. The user ID is passed to the client (in a hidden field) so that I know which user to update when the form is posted back to the server. My question is, how can I guard against users changing the ID in the DOM, thereby updating a record to which they should not have access?
The only ways I can think of are:
Save the user ID in the session. (Painful).
Run a salted hash on the user ID (and perhaps other form elements) and include it also as a hidden form element. (Not particularly secure?)
Are there other approaches?
Thanks!
EDIT: Hey, some great responses coming in. Note that the logged in user and the user being edited may be two different users, e.g. a Manager is editing a Staff record.
The best way to do this is to just check after submission if the user has the right to edit that user.
Don't pollute the session with this data, because it can get messy, for example when a user opens the same page multiple times.
It depends somewhat on the conditions under which the user is allowed to edit it.
At the heart of it, it comes down to:
Authenticate the user
Check if the user is authorized to make that change
Authenticating the user is usually a case of "Do the username and password match?" or "Is there an active session with a logged in user associated with it?"
Authorization depends on your business logic. It might be "Is the logged in user the same as the user being edited?" or "Does the user being edited have a manger field containing the id of the logged in user?" and so on.
In the first case, storing the user id in the session shouldn't be painful. In the second case, you just do a database lookup as one of the first things you do in the script.
Why are you relying on a hidden field for knowing which record to update? If the user is logged in you should already have the user_id of him with you on the session.
So you can just find which record to update by finding which user is logged in.
As mentioned, the fastest and painless way to sort this would be to stick the USER_ID in the session, period.
Comments saying that you "pollute" session with that information are plainly uneducated, ignore them.
The other thing I noticed in comments is the "check if the user has the rights to edit the entry" which implies there's some sort of hierarchical system in place, which seems not to be true.
Alternative to session storage would be, as you assumed already, obfuscating the USER_ID value in the hidden field somehow. You could either encrypt it, or instead of integer ID - you could use GUIDs but that has implications of its own, tho it makes it incredibly hard for someone to "guess" the correct GUID to mess around with the records.

[PHP]How do I count users online and users logged in, what method?

I've made a log in script for my site, the session stuff basically look like this.
if($_SESSION['loggedin']=="Yes"){
//user online stuff
}
For all other users the session is set
$_SESSION['loggedin']=="No";
How can i display active session that are set to yes or no? should i work anything with mysql tables and use crontabs? or should i count files in tmp(session directory) on apache?
What are the best methods and how can I do it?
Crontab is not necessary here. You can store last activity date and time somewhere (mysql database?), and use simple select, which would show amount of users, who were active within some timeout.
This table can be used for server-side tracking of logged in users. Table may also contain some additional information, like IP address, X-Forwarded-For IP etc.
You can store the users in a database, along with their login information, and check that every time you want to authenticate a user. This is far safer than using just session variables to authenticate.
You can count the number of users that are logged in by setting a bit for the user's record when they log in and turning the bit off when they log out / session expires, and counting the number of these bits that are on to see how many people are logged in.
If you need to display the actual users currently logged in, you're better off using a column in your users mysql table to track the current login state, and doing a periodical request via a cronjob, and store that info in a .txt file so that you can do the query just once for all logged in users and share the result by including it in your rendered html.
The other method (reading inside the session folder storage) is possible but more complex and probably less effective, although i haven't done any benchmarks. It just feels very hacky.

Users database structure that allows multiple simultaneous logins to same account

A feature that is currently missing from one of my web apps is that a single user can only be logged in on one machine at a time. That is, if the users logs in elsewhere, his previous session will be logged off.
This is due to my current users table having the columns:
user: id, username, hash, salt... cursession
When each user logs in, the session ID is put into the "cursession" field and on each page-load, is checked against the database. As a result, only one "session" can be active at a time.
Is the current table structure and method secure and standard? This system was pretty much improvised, and I have no professional experience.
What would be a way to allow multiple simultaneous logins? I'm simply thinking of adding a "sessions" table with more userid-cursession relations, but what's the standard method for doing this?
I propose that you put the current logged in userid in the user's session (as a session variable), and drop the cursession field from the table altogether. You don't need to reinvent session handling since PHP already has it built-in.
That way the user can be logged in at multiple computers at once. Session variables are safe too, since they're not manipulated by the browser. The only thing kept in the browser is a session id which identifies the current session, all other data is stored on the server-side. The only thing that will happen if the user changes his browser cookies is that he will be logged out (start an empty session), so he can't force himself to log in as someone else.

Categories