I have a site with two user classes – Admins and Guests. Expectedly, Admins have accessed to certain features which normal Guests don’t. Currently, the user flag (admin/guest) which seperates admins/guests is stored in a cookie in a X:Y format where X is the user flag (1 for admin, 2 for user), and Y is the unique userid of the user in the database.
Privilege escalation can be done by changing the “X” in the cookie. Thus, I’m wondering if there are any ways to prevent this from happening? Ty!
Your method is subject to multiple security vulnerabilities: it allows anyone to gain admin access AND it allows intruders (non admin, non-guests) to modify cookie values to mis-identify themselves completely. Building on Quentin and pinouchon’s answer, you should use sessions to control user access levels… this will always be safer than storing flags on the clients side. This way the only value stored on the client side is the session ID which you can then use to either grab an existing session value (
$_SESSION['privilege_level']) or against a database of user-privileges.I’m a little reluctant to even post this, but if, for some reason, you absolutely cannot use sessions, at the very least you should avoid sending unencrypted/hashed cookie values. It’s nowhere near as secure as using sessions, but you could store something like X:Y:Z , where x is the encrypted userID, Y is the encrypted permission flag, and Z is a monstrous salted hash that includes X,Y,User Agent, IP, etc. Then re-create the hash whenever the user does something and make sure that it matches the hash in the cookie (this will make it a little harder for someone to take over someone else’s role, and it will make it harder for a user to manually alter their role.