There are many ways to work with PHP, and that's what makes it a great language. It's extremely powerful, has a great community, and it's easy to learn. One of the great use cases for PHP is websites, and more specifically, user-based websites such as customer areas, or dashboards. When working with users, your code and the information it displays need to be user-specific. By that we mean, that user A shouldn't see user B's data and vice versa. In fact, this data, or as it's better known in the security industry, information exposure, is a very serious issue, if it occurs.
One of the main ways to prevent information exposure is knowing who's who. Typically, you'll ask all users to authenticate themselves somewhere along your website or app process. That gives you a chance to;
- Force users to prove they are who they say they are
- Once proven, you can make sure that displayed information relevant to the right user
- Undertake per-user actions, like audit logging
Once you a user have proven who they are, by correctly passing the authentication, typically, a correct matching username and password to what you have on file (in the database), you now need to remember this person on every different page or website request. Once logged in, you don't want to make the user re-login again or prove who they are every time they make an action, that will most definitely drive them mad nor is it a good user experience. To do this you'll use a PHP session. Using what's called a session in PHP is a great way to store user-specific information, for a temporary state. Let's explore what a PHP session is, how you can use it in your code base, and some associated risks that could occur when using PHP sessions.
What is a PHP session?
A PHP session is a temporary state that lives as long as the browser window is active. Typically, a browser will clear session data on close. This is because session data in their nature aren't meant to be permanent. It means it ensures data (or in this case, authentication) can be re-obtained. Each user is given a unique auto-generated ID, called PHPSESSID which is then stored on the server. That same session ID is given to the user via a cookie. The cookie is saved on their browser for the duration of their active session. With each request, the session ID is passed in the request, which helps identify each person.
Which parts of the PHP session are secure?
All the data associated with a PHP session (baring the ID), are stored on the server, not stored on the client's machine. That means it's not directly accessible, and therefore the data is then protected and unable to be tampered with. It also means this same data cannot be accessed by unauthorised users. Therefore the session cookie data will only ever contain the ID, if it contains anything else, it's been tampered with on the client side, or sent over insecure HTTP, and therefore will not work.
How do I use PHP sessions?
Using sessions in your PHP code is easy. First, you need to start the session, like the example below. The code below also can resume a pre-existing session.
// Start new (or resume) session
session_start();
Then use the super global variable $_SESSION - which is a variable that is available throughout the whole scope of a script, and is an associative array that can contain any session variables, like the example below.
// Add data to a session
$_SESSION['country'] = 'Europe';
You can also close a session and remove all session-related data, you should use session_destroy, like the code example below. Or if you're looking to wipe it's data but keep the session alive, use the session_unset function.
// Close/end a PHP session
session_destroy();
// Keep session but clear data
session_unset();
You can also give the session a name instead of using PHP's built-in name, which is useful if you want to provide different or custom session-based logic. To do this you can use the session_name function in PHP. The chosen name must use at least one letter, contain only alphanumeric characters, and must be called before session_start().
// Set the session name
session_name('MyWebApp');
What are some risks associated with PHP sessions?
In general, PHP sessions are secure and can be used to store user data that creates part of your application flow. They are very common in many leading CMS (content management systems) such as WordPress, Laravel, and enterprise website applications. But if used and configured incorrectly, what are some risks with PHP sessions? Let's explore those risks in more detail.
Session Hi-jacking
If for example, an attacker was to obtain the cookie session ID, via an unencrypted HTTP call, commonly known as a man-in-the-middle attack, they could potentially use it to gain access to that user's session, by-passing the need for any authentication. Ways to prevent this include, always using HTTPS, especially when sending sensitive data across the internet. That includes login and register screens. Another mitigation method is to regenerate session ID periodically. This is a key reason why sessions expire, and why PHP garbage collects old PHP sessions.
Session Fixation
Much harder for an attacker to gain access this way due to the way PHP generates session IDs, but an attacker could potentially set their own session ID to gain access. It's always good practice to clear all session data on a user logout or if a user's privilege level changes.
Session Data Injection
We briefly touched on this topic, but as a cookie is saved client side, it is possible and quite easy for someone to edit the contents of their session cookie. This becomes very important if you're not using PHP's built-in naming convention or cookie parameters. It's therefore important not to simply rely on any user data, and that includes session cookies. Sanitising all data that arrives from the user to the user will help mitigate this risk.
Conclusion
- PHP sessions are secure to use and store important information
- Sessions are cookie-based, so must be set before anything is output to the user's browser
- Using the session_start function will return true if successfully started and false if not
- Before going custom; PHP does a good job of handling garage collection and setting unique session IDs
- Marking the session as HTTP only (accessible only through the HTTP protocol) is a good way to prevent XSS attacks, which is PHP's default choice
- Use the session_unset function to clear the values from session whilst keeping the session alive
- Use the session_abort function to discard changes made in that current session, without ending the session
- Use the session_destroy to wipe all session data and end the session itself