HyperText Transfer Protocol started off as a stateless protocol. This means that every request to the server is self-contained, it carries all the context that the server needs to serve the requested web page. Every message that the client sends to the server can be processed on its own – the server does not maintain the state, nor information about the connection.
Web applications need a way to preserve a context about the visitor – from logged-in user identity, shopping cart in ecommerce stores, to longer-lasting data like purchase history or chat history in social network applications.
This is why it was necessary for HTTP, and all the applications building on top of it, to find solutions to manage this inherent statelessness in HTTP. The main solution is cookies.
PHP is maybe the most used programming language for the web (w3techs give it almost 80% ) and it has its own solution for this – PHP sessions. In this article we will describe PHP sessions mechanisms, we will explore PHP session security, and how to secure PHP session cookies.
We will see what are potential vulnerabilities, and php session security best practices.
HTTP and state
HTTP has been made extensible through its headers from the early days. This means that functionality can be added to HTTP requests and responses through user-definable headers.
Headers are fields in every request and response that can contain various pieces of metadata.
Cookies have been published as an addition to the HTTP standard by the IETF in 1997 , and the specification has advanced since then to be finally defined in RFC 6265 , titled HTTP State Management Mechanism .
Cookies are defined by IETF as a mechanism that consists of HTTP header fields that can be used by the servers to store pieces of data (state) in HTTP clients. This makes it possible for the server to keep a stateful context, called session, across multiple HTTP requests.
The user’s browser (the client) then sends back these cookies to the server on subsequent requests, making it possible for the server to reconstruct states, such as buyer’s journey, a shopping cart, or a social media account.
We can distinguish between session cookies and persistent cookies. Session cookies are transient – they only last for the duration of that particular browser session. They live in the browser memory. Because they expire when the current browser instance is shut down, they do not have an expiration date.
Persistent cookies have an expiration date, they are meant to last for a specific length of time.
They are used for things like the personalization of user experience, session management – including users logged in / logged out state, carts, and for tracking of user’s behavior.
Cookies usually store a very limited amount of data (maximum is 4096 bytes per website), and they are stored on visitor’s machines. This makes cookies limited and insecure – not enough to provide for the session needs of modern websites on their own.
Keep Your Apps Secure on Cloud
Cloudways offers 2FA, free SSL, and more advanced security features on managed servers that keep your application safe.
PHP Sessions
PHP as a web programming language belongs to the application layer. PHP builds on HTTP cookies to provide a mechanism to maintain context across multiple requests. For this, it combines custom, specific cookie header with its own session handler class:
SessionHandler implements SessionHandlerInterface , SessionIdInterface { /* Methods */ public close ( ) : bool public create_sid ( ) : string public destroy ( string $id ) : bool public gc ( int $max_lifetime ) : int|bool public open ( string $path , string $name ) : bool public read ( string $id ) : string public write ( string $id , string $data ) : bool }
This mechanism can be extended or completely rewritten by inheriting the SessionHandler class or by implementing SessionHandlerInterface.
In PHP, sessions are by default persisted as files on the server. Files carry names of their respective session ID-s. When the session is initiated, PHP sets a PHPSESSID cookie with a session id. Later, when the visitor’s browser returns that cookie on each request, the server associates it with the session data in the file related to that session. The result is a continuous session state across multiple pages on a website.
Using Sessions in PHP
A session in PHP can be started with a call to a function session_start() . This function either starts a new session, or restores an existing session passed to the server in a cookie, or in POST or GET request parameters. $_SESSION superglobal array is then used to set or to get variables in a session.
If we then want to use session variables on other pages of the same website, another PHP document needs to use session_start() . This will make $_SESSION variables, which may have been set on other web pages/documents, available on the current one.
session_close() commits the changes to $_SESSION to the disk
session_destroy() function will destroy all the session data. To fully remove the session, it is also necessary to unset the session ID, and explicitly delete the session cookie. Beyond these basics, PHP has a host of other functions for session handling .
The functionality that PHP sessions try to provide – persistent data across the visits to pages of a website – is indispensable to modern websites. PHP sessions implementation however is a point of contention.
Since session data in PHP is written to a file on the server by default, and the file is locked during the script execution, this can present challenges in terms of performance and scaling.
PHP sessions also present challenges to the normal caching mechanism – caching pages with PHPSESSID cookie set could seriously compromise the website while bypassing the cache for pages with PHPSESSID would mean bypassing cache on the entire website.
And then, there are security issues.
PHP Sessions security issues
PHP sessions are a step forward in regards to security compared to a system where all the session data is stored within cookies. PHPSESSID cookie merely stores a reference ID for a session file that lives on a server.
PHP default setting for a path to save session files, which we can find in php.ini configuration files is session.save_path = “/tmp” . This means that session files could effectively get compromised by other users.
This issue is particularly alarming when we recall that the majority of PHP-powered websites live on shared servers with multiple tenants.
The most common of all session exploits is Session Hijacking.
What is a Session Hijacking Attack?
Session Hijacking happens when a malicious party gains illegal access to another user’s session. The attacker will first obtain the session ID belonging to another user. Then he will use this ID to gain full access to the other user’s session. The session ID is enough for the server to give access to the respective account.
Theoretically, the Session ID could be obtained by prediction or guessing (brute force), but the most likely way is for the Session ID to be stolen. Both brute force attack, or predicting the ID is much less likely to happen.
There are several vectors by which an attacker can gain access to users’ Session ID.
Types of Session Hijacking Attacks
Session Hijacking can happen in many different ways – here we mention only those which are more notorious:
- XSS or Cross-Site Scripting – this is an attack that happens when a third party succeeds to inject javascript into the body of a website visited by the victim. Let’s say that a website XY uses GET variables, and does not properly sanitize them.An attacker can use javascript in a GET request and get it injected into the body of a web page, gaining the same level of access as the website’s own javascript. For example, it can get the content of the PHPSESSID cookie, and then send it to the attacker.
- Session Sidejacking – this type of attack happens with Man In The Middle attack vector – in situations when the attacker is positioned between the source and the destination of the traffic. The attacker will listen to requests and responses, and, unless the traffic is encrypted, he can capture the Session ID.
- Session Fixation happens with vulnerable web applications, which don’t insist on always setting a new Session ID upon user authentication, but instead accept an existing Session ID when it exists. In this type of attack, the attacker will forge a valid, but unused Session ID, and then, through various schemes, make a valid user authenticate using that ID. After that, having possession of the authenticated user’s ID, the attacker gains access to the user’s session.
- Session Prediction – in this type of attack, the attacker will usually have some knowledge of how the application generates Session ID-s, and will then try to guess other user’s IDs using the same method. This is where the randomness of Session ID-s generation plays a big role.
What Can An Attacker Do With a Session That Was Successfully Hijacked?
Once an attacker gains access to the session that belongs to a legitimate user, the server will grant him all authority that the original user has. As such, the Session ID can be likened to a key that grants its owner access to the house, regardless if he was the house owner or not.
This attack will often be focused on users & sessions with administrative access, so in those cases, the attacker will gain administrative rights on the compromised website.
PHP Session Security Best Practices, and importance of PHP session.cookie_secure flag
Before continuing to different measures we can take to prevent our sessions from being exploited by attackers, it is important to say that vulnerabilities connected to PHP sessions are not something specific to the language itself. They are not an inherent flaw of PHP – other technologies require similar measures to mitigate these same vectors of attack.
So what are common-sense measures we can take to mitigate Session hijacking attacks?
- XSS (Cross-Site Scripting) Attack – mitigation against this type of attack is not sessions-specific. The website needs to prevent any kind of user input from being executed in the visitor’s browser. This simply means that any user input, through forms or GET parameters, or other needs to be sanitized before it is used. This is a general security measure for web applications, for this and other types of attacks (e.g., SQL injection). The main two functions in PHP used to sanitize strings are htmlspecialchars() and strip_tags(). htmlspecialchars() converts special characters into html entities, and strip_tags() will simply remove all the HTML tags, including <script> tag.Another measure we can take to protect against this type of attack is a php.ini setting – session.cookie_httponly.HttpOnly cookies were first implemented in now-infamous Internet Explorer 6, to later be adopted by other browsers. session.cookie_httponly flag adds an instruction to the browser not to allow client-side javascript to access the cookie: it will add an optional HttpOnly instruction to Set-Cookie response header.
- Session Sidejacking – this line of attack can be prevented with SSL encryption implemented along the entire request – response surface. However, even if the connection is fully encrypted, there still remains the possibility of leaking the session cookie.
For example, after the visitor/client has already visited the website and there is an active session with PHPSESSID cookie in the browser – the visitor may try to visit the same website over a public network – and when he enters the bare website address (without the protocol scheme), browser will first send the request to the insecure, http version of the address. Only then, as a response, will it be redirected to https version (301 redirect).But in itself, this insecure redirection roundtrip will be enough to transmit previously existing session cookie, which can be intercepted by the attacker and used to hijack the session.How to make php session cookies secure?There is a settings flag that can be used to eliminate this threat in PHP -session.cookie_secure . This setting is by default set to off – but, when it is turned on , it will instruct the user’s browser to only transmit session cookies over an encrypted connection – it will add secure instruction to Set-Cookie response header.
- Session Fixation – when an attacker gets a genuine user to set a predefined Session-Id – is most often used in URL-based session management. This means that Session ID is contained within the URL as a GET argument. Another possibility is a hidden form field in a form created by the attacker, then tricking the victim to sign in through that form. There are various possible ways to fix a session through manipulating cookies, as well. The Open Web Application Security Project (OWASP) has more examples of Session Fixation attacks.
The main PHP setting related to this particular security risk is session.use_trans_sid. This setting, when set to 1, will enable “transparent session ID-s” – it will allow PHP to pass the session ID in urls in cases when the visitor’s browser doesn’t support cookies. This is by default set to 0, which means transparent SID-s are disabled for security purposes. By setting use_trans_id to 1, for example, we risk that someone could access the session (on a public computer, for example), by accessing the url containing session ID in the browser’s history, or by examining logs of devices in the middle.session.use_only_cookies is another PHP setting (set to On by default). This setting disables completely the use of url parameters as session ID-s.So, in order for Session ID-s to be usable in URL-s, we would need both of these settings as follows:session.use_trans_sid=1
session.use_only_cookies=0
- Session Prediction – to prevent this, web applications need to generate Session ID-s with enough length and sufficient level of randomness (entropy). The default PHP settings with modern (7.1.0+) PHP are probably safe enough, but in case the application deploys custom session solutions, this is something to be aware of.PHP settings we can use to change length/entropy are session.sid_length and session.sid_bits_per_character.PHP versions prior to v7.1.0 also had session.hash_function, session.hash_bits_per_character, session.entropy_file and session.entropy_length as additional settings variables to more explicitly set the Session ID entropy. We can find the full reference of PHP session settings here.
Improve Your PHP App Speed by 300%
Cloudways offers you dedicated servers with SSD storage, custom performance, an optimized stack, and more for 300% faster load times.
Conclusion
PHP sessions security is an ongoing concern. PHP web applications (such as WordPress, or Laravel framework) often find native PHP sessions inadequate or insecure for their needs, and choose to roll out completely custom solutions and forego PHP sessions, while others like Zend framework, choose to build customized solutions on top of PHP native sessions. Whichever path we choose, it is important to be aware of all the security and PHP performance concerns.
In this article, we covered some fundamental PHP session security concerns we need to keep in mind, and PHP security best practices. As such, it is more of an overview than an exhaustive list of all the caveats, so we encourage readers to also do their own research when it comes to PHP session & cookie security.
Do you have anything to add? Let us know in the comments.
“Is a PHP session secure?
PHP sessions are only as secure as your application makes them. PHP sessions will allow the client a pseudorandom string (“session ID”) for them to distinguish themselves with, but on the off chance that the string is intercepted by an attacker, the aggressor can imagine to be that client.
Can PHP session be hacked?”
Sessions are NOT serverside, they are put away on the clients local machine you’ll be able go in your treats and explore for a cookie called phpssid beneath your domain name. Yes they can be hacked, and this can be in reality a really common strategy of hacking
Owais Khan
Owais works as a Marketing Manager at Cloudways (managed hosting platform) where he focuses on growth, demand generation, and strategic partnerships. With more than a decade of experience in digital marketing and B2B, Owais prefers to build systems that help teams achieve their full potential.