So I'm fairly new to PHP and was wondering what is secure and what isn't with the user sessions.
So theoretically I have this site with user registration that saves user data in MySQL. When the user logs in the site it takes the id that corresponds with the username and password given in and save it to the $_SESSION variable. The site later on uses the $_SESSION value to get data from the database.
I would assume this would,'t be considered a secure website just from this basic stuff, but can the user change the $_SESSION value to be another users id with ease, or something like that, or if it's not that easy, what do I have to pay attention to, to make it more secure?
Explanations of why this is secure or why it's not secure/some info in PHP session security would be of great help.
A session is stored on the server and cannot be accessed by the user. It is used to store information across the site such as login sessions.
The user cannot edit these values however the session's ID is stored on a computer through a cookie as a long random string. If an unauthorized user gains access to these strings it is possible for them to access the site
Related
Is it possible to set a cookie with the session that has been created and with the session ID and then retrieve the session from the cookie next time you visit the page. I am trying to make a remember me button on my login page and wondered if this could be done this way.
Do not try to prolong a PHP session in order to build "Remember Me" feature. It's much better to re-initialize the session.
The most common scenario is this:
When a user comes to a website with checked "Remember Me" checkbox, the website generates a unique code (a pretty long random string) and stores it in the cookies and a server side database.
When the user closes a browser the session closes, but cookie stays.
The next time the user comes the server will see the cookie, find it in the database and authenticate him based on the code instead of user/password pair.
This would be a good starting point, but in addition there are several enhancements are possible:
You could save a username in the cookie along with the unique code. It's safer and faster to authenticate using this pair.
You could save a user's IP in the database, so that authenticating data will work from this IP only.
Instead of generating the unique code and saving it to the database, you could build the code on the fly as a hash based on user password plus salt. This saves your database from write operations.
Based on security/speed requirements there could be variations of this scenario, but the base stays the same: mark a user using cookie, re-authenticate him once he comes back.
I am using PHP and Codeigniter to do this. Currently I am just saving a cookie to the user with their username and a $logged_in variable set to true. Then when they try to access a page, I check for the status of their $logged_in, and if they are, they're free to access.
It occurs to me that this may not be the safest way to go about this. Is there a better tactic I should be using?
It's not safe at all. Cookie is considered user input and it can't be trusted in any case.
Use sessions instead.
Also you could use some sort of custom login encrypted code (I'd personally suggest SHA1) that is matched against the login code in the database and is refreshed every, let's say, 5 minutes.
CodeIgniter offers a nice solution to this problem - You can use Database Sessions.
With Database Sessions, all the data you put in a session is stored within your SQL database. The user gets a cookie with a unique session ID that changes on a regular basis. The session ID along with IP and User Agent is used to match up the user with their session data, thus making it impossible for users to tamper with their own session data, and very hard for them to hijack someone else's session.
You can read more about CodeIgniter Database Sessions in the CodeIgniter User Guide.
I am trying to understand security when it comes to session cookies in php. I've been reading a lot about it, but I still lack the specifics. I need the basics, someone to show examples.
For example: Do I place session_regenerate_id() before every session cookie? What more shall I think about. I am asking about specifics in code - examples if possible.
Thank you very much.
I am using 4 session cookies after logging in.
SESSION "site_logged_in" = true
SESSION "site_user_nr" = the number of the user to access user_table_nr
SESSION "site_user_id" = the user's id to use when changing data in tables
SESSION "site_user_name" = the name of the user to display on page
When I check if the user has access, I check if all 4 cookies are set, and if site_logged_in is set to true.
Are there better ways? Do I have the completely wrong idea about this? Can users easily be hacked?
In fact you need to have only one session in your website. When you call session_start() session is being created on server and user automatically gets session cookie. Think like session is a some sort of container that placed on the server, you can put whatever you want in that container. However session cookie is just a key to access that container on the server.
It means that you can safely put some data in the $_SESSION and only the user that have cookie with matching session id can read it.
About users being hacked. Yes they can be hacked as long as you don't use HTTPS connection, because cookies and all other data is being transferred in clear text, so if someone intercept users cookie he can access the data stored in the session.
Always use a security token for logging users. This security token could be generated by using crypt(). After logging users in, change the security token periodically until they log out. Also keep the server backup of all the session variables including the security token (in a database). This would also help you to track user login history.
One more personal suggestion: Never use any data from the database as session variables without encrypting it with any of the hashing functions or functions like crypt().
The session information is stored server-side. What you should check is that they're logged in, and that they exists/can log in (in case of deletions/bans).
As you're checking they exist/can log in, you can pull the other information from the database such as name, nr and so on. All you really need is a key called 'logged_in_user' or something that stores the ID of the logged in user. As Alex Amiryan said, the cookie can be copied, so you might also want to store the IP address of the last accessing view in the session, so you can try to ensure security.
I have created a registration/login system for my members area. Once the user has logged in I want to store a session variable that I can use to retrieve data associated to the user from the database.
Should I in encrypt the variable in any way? The data I want as a variable will either be the username or the id, which is best?
Should session ids be regenerated in anyway and when??
Data storage in session is considered to be "safe", so you dont need encrypt-decrypt it.
You should regenerate your session id after a successful login/logout. For security reasons, I would reccomend to ask the user for his password if he want's to perform a critical action (changing important data, deleting account or submit an order for example).
As AurimasL stated, you don't have to worry about session data on the server side. I reccomend this reading, if you are on a shared host, because then there are some security aspects: http://phpsec.org/projects/guide/5.html
Session IDs are stored like a cookie on the client's machine, and are passed back to the server for every single request. This is how PHP determines what information to load into a session once it receives the request.
Since sessions live on the server and not on the client, you only need to worry about session hijacking in regards to whether the information stored in them is secure or not. The answer to your question is no, I would not try to encrypt the information that is stored in session.
Just an add in the comments bellow,
Keep in mind that creating a sessions are expensive for your server app. Sometimes is a good idea stores the id in the session and other informations in cookies (informations that dont need security as the username).
I'm developing a web application using Codeigniter. When a user authenticates with my site I'm currently storing their 'user-identifier' in my session cookie (which I have enabled encryption on). Several of my model classes use the value in 'user-identifier' parameter of the session/cookie to make changes to properties of user accounts.
My concern is that I'm wondering if it's possible for someone to take a valid codeigniter-session cookie with a user-identifier that I've set, change the user-identifier's value to the value of a different user, and make changes to another user's account. Would codeigniter/php sessions create an error if someone attempted to change a property of a session cookie?
Open your /application/config/config.php, locate "sess_use_database" and change it to "TRUE" if you haven't already. This way all session variables will be stored in a database table and session cookie will only contain session id string.
For added security, you can also change "sess_match_ip" to TRUE. This way if someone steals your user's cookie and tries to pass it as their own, session will be destroyed.
"if
it's possible to take a
valid codeigniter-session cookie
change the user-identifier's value to
the value of a different user, and
make changes to another user's
account."
My answer is not really CI related, so please bear that in mind.
When you auth the user "username1" what should be sent back to the client, for auth purposes, should be a hash that the server correlates to that user. All communication between the client and the server will rely on that hash.
The server will generate a unique hash per user and the hash should have a short time to live. Can someone capture a hash and pass as that user? Certainly. That's why you should also check for the user's Agent and IP to check if they match the hash in order to prevent session hijacking.
NEVER DO THIS:
If seen some new developers storing the username in a cookie and reliing on that client sent variable to update their databases. Never do this. Do not ever, ever trust the client. When the server gets the client's hash it should check if it belongs to an authenticated user and grab the user_id (variable to update the user data) from the server. NEVER from the client.
I'm not sure what your "user identifier" is exactly. The general rule is, don't store anything in the session cookie but the session ID. Store everything else (like a user ID) internally on server side, and retrieve it using the session ID.
If the user changes the session ID (which is a random string), a new session will start. The idea behind the session ID is that it's impossible to guess other user's IDs - that's why it's random, and so long.